Python Day08

lambda表达式
匿名函数是在创建时使用lambda关键字的函数。在定义的时候不使用def,所以称为匿名函数。
我们可以向lambda形式的函数传入任意数量的参数,但是返回值只有一个。
优点:
在用Python写执行脚本的时候,使用lambda可以省下定义函数的过程,使代码精简。
对于一些抽象且使用次数少的函数,使用lambda不用考虑命名问题。

>>> mult = lambda val1,val2 : val1*val2
>>> mult(2,3)
6
>>> result = lambda x : 2*x + 1
>>> result(2)
5
>>> 

Python内置函数filter()
filter(function, iterable)
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列(可迭代对象),序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

>>> def odd(x):
	return x % 2

>>> temp = range(10)
>>> show = filter(odd,temp)
>>> show
<filter object at 0x000000DBBF979D48> #返回一个迭代器对象
>>> list(show)   #如果要转换为列表,可以使用 list() 来转换。
[1, 3, 5, 7, 9]
>>> list(filter(lambda x : x%2 ,range(10)))
[1, 3, 5, 7, 9]
>>> #过滤出1~100中平方根是整数的数
>>> import math
>>> def is_sqr(x):
	return math.sqrt(x) % 1 == 0

>>> tmplist = filter(is_sqr,range(1,101))
>>> print(list(tmplist))
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> 

Python内置函数map()
map() 会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

>>> list(map(lambda x : x * 2,range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list(map(lambda x , y : x+y , [1,2,3,4,5] , [6,7,8,9,10]))
[7, 9, 11, 13, 15]
>>> 
>>> list(filter(lambda x : x%3==0 , range(101)))
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
>>> [ i for i in range(101) if not(i%3)]  #用列表推导式代替
[0,3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
>>> 
>>> list(zip([1,3,5,7,9],[2,4,6,8,10]))
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]  #将元组改为列表形式
>>> list(map(lambda x,y : [x,y],[1,3,5,7,9],[2,4,6,8,10]))
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]

>>> def make_repeat(n):
        return lambda s : s * n

>>> triple = make_repeat(3)
>>> print(triple(8))
24
>>> print(triple('i love you'))
i love youi love youi love you
>>> 

递归
在编程上,递归表现为不断调用自身的行为。汉诺塔,目录索引(因为你永远不知道这个目录里边是否还有目录),快速排序(二十世纪十大算法之一),树结构的定义等如果使用递归,会事半功倍。

递归需要满足的条件:
1.函数调用自身
2.设置了正确的返回条件

递归的优点:
1)规模大的问题转变成规模小的问题组合,从而简化问题的解决难度(例如汉诺塔游戏)。
2)代码简洁易懂(前中后序的二叉树遍历的递归算法)
递归的缺点:
1)一旦大量的调用函数本身空间和时间消耗是“奢侈的”
2)容易错误的设置了返回条件,导致递归代码无休止调用,最终栈溢出,程序崩溃。

#迭代方法求阶乘
def factorial_1(n):
    result = 1
    for each in range(1,n+1):
        result *= each

    return result

#递归方法求阶乘
def factorial_2(n):
    if n == 1:
        return 1
    else:
        return n*factorial_2(n-1)
  1. 使用递归编写一个 power() 函数模拟内建函数 pow(),即 power(x, y) 为计算并返回 x 的 y 次幂的值。
  2. 使用递归编写一个函数,利用欧几里得算法求最大公约数,例如 gcd(x, y) 返回值为参数 x 和参数 y 的最大公约数。
def power(x,y):
    if y == 1:
        return x
    else:
        return x * power(x,y-1)


def gcd(x,y):
    if y:
        return gcd(y,x%y)
    else:
        return x
#用迭代方法计算Fibonacci数列
def Fibonacci_1(n):
    if n < 1 :
        print("输入有误")

    n1 = 1
    n2 = 1

    while (n - 2) > 0:
        n3 = n1 + n2
        n1 = n2
        n2 = n3
        n = n -1
    return n3
        
#用递归方法计算Fibonacci数列
def Fibonacci_2(n):
    if n < 1:
        print("输入有误")

    if n == 1 or n == 2 :
        return 1
    else:
        return Fibonacci_2(n-1) + Fibonacci_2(n-2)

用递归实汉诺塔

def hanoi(n,x,y,z):
    if n == 1:
        print( x ,"---->", z )
    else :
        hanoi(n-1,x,z,y)        #将n-1个盘子从x移到y上
        print( x ,"---->", z )  #将最底下的盘子从x移到z上
        hanoi(n-1,y,x,z)        #将y上的n-1个盘子移到z上

n = int(input("请输入汉诺塔的层数:"))
hanoi(n,'X','Y','Z')

用递归方法实现十进制到二进制的转换

def DecToBin(num):
    temp = ''
    if num :
        temp = DecToBin(num//2)
        return temp + str(num%2)
    else:
        return temp

print(DecToBin(10))

写一个函数get_digits(n),将参数n分解出每个位的数字并按顺序存放到列表中。举例:get_digits(12345) ==> [1, 2, 3, 4, 5]

result = []
def get_digits(n):
    if n > 0:
        result.insert(0,n%10)
        get_digits(n//10)
get_digits(12345)
print(result)

用递归方式求解回文字符串

def is_palindrome(string,start,end):
    if start > end:
        return 1
    else:
        return is_palindrome(string,start+1,end-1) if string[start] == string[end] else 0

string = input('请输入一串字符串:')
length = len(string) - 1

if is_palindrome(string,0,length):
    print('"%s" 是回文字符串。'% string)
else:
    print('"%s"不是回文字符串。'% string)

字典
字典是一系列无序的元素或条目的集合,是键值对的组合,每个值value对应一个键key。字典中的值可以重复,但是键是唯一的。
也叫“映射”、“哈希”、“散列”或者“关系数组”
Python对键的要求相对要严格一些,要求它们必须是可哈希(Hash)的对象,不能是可变类型(包括变量、列表、字典本身等)。但是Python对值是没有任何限制的,它们可以是任意的Python对象。
创建字典

>>> dict1 = {'name':'Jack','sex':'male','score':99}
>>> dict1
{'name': 'Jack', 'sex': 'male', 'score': 99}
>>> #Python提供了一个内置的函数dict()用于创建一个字典
>>> d1 = dict({1:'red',2:'yellow',3:'green'})
>>> d2 = dict([(1,'red'),(2,'yellow'),(3,'green')])
>>> d3 = dict(1=red,2=yellow,3=green)
SyntaxError: keyword can't be an expression
>>> d3 = dict(red = 1,yellow = 2,green = 3)
>>> d1
{1: 'red', 2: 'yellow', 3: 'green'}
>>> d2
{1: 'red', 2: 'yellow', 3: 'green'}
>>> d3
{'red': 1, 'yellow': 2, 'green': 3}
>>> #访问字典
>>> d1[1]
'red'
>>> d1.get(1)
'red'
>>> d1[4]       #直接访问不存在的键会报错
Traceback (most recent call last):
  File "", line 1, in <module>
    d1[4]
KeyError: 4
>>> d1.get(4)
>>> print(d1.get(4))     #用get()方法访问则返回空
None
>>> 

在字典初始化的时候,字典的键是任何顺序的。但在打印时,是按照排序后的顺序打印的。因为字典有一个内部的排序机制。pop()方法也是弹出排完序之后的最后一个值。

>>> dict1 = {'name':'John','age':27}
>>> dict1['age'] = 30
>>> print(dict1)
{'name': 'John', 'age': 30}
>>> dict1['address'] = 'China'
>>> dict1
{'name': 'John', 'age': 30, 'address': 'China'}
>>> dict1.pop('age')  #给定键,弹出值
30
>>> dict1
{'name': 'John', 'address': 'China'}
>>> dict1.popitem()  #弹出一个项
('address', 'China')
>>> dict1
{'name': 'John'}
>>> dict1.clear()
>>> dict1
{}
>>> 

fromkeys() 用于创建字典,接收两个参数,第一个参数作为字典的 key,第二个参数作为字典的 value。
fromkeys方法是直接创建一个新的字典,不要试图使用它来修改一个原有的字典,因为它会直接无情的用把整个字典给覆盖掉。

b.update(e)方法是把一个e更新到b中,e可以是字典,也可以键值对

>>> dict1.fromkeys((1,2,3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1,2,3),'Number')
{1: 'Number', 2: 'Number', 3: 'Number'}
>>> dict1 = dict1.fromkeys(range(5),'肖战')
>>> dict1
{0: '肖战', 1: '肖战', 2: '肖战', 3: '肖战', 4: '肖战'}
>>> for each in dict1.keys():
	print(each,end= ' ')
0 1 2 3 4 
>>> for each in dict1.values():
	print(each,end = ' ')
肖战 肖战 肖战 肖战 肖战 
>>> for each in dict1.items():
	print(each,end = ' ')
(0, '肖战') (1, '肖战') (2, '肖战') (3, '肖战') (4, '肖战') 
>>> #赋值与浅拷贝
>>> a = {1:'one',2:'two',3:'three'}
>>> b = a.copy()     #b是浅拷贝
>>> c = a            #c是赋值
>>> id (a)
348173242520
>>> id (b)
348173698376
>>> id (c)
348173242520
>>> c[4] = 'four'
>>> c
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> a
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> b
{1: 'one', 2: 'two', 3: 'three'}

>>> c = {4:'four'}
>>> b.update(c)
>>> b
{1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> 
>>> data = "肖战,男,28"   #利用字符串的分割方法初始化字典
>>> MyDict = {}
>>> (MyDict['name'],MyDict['sex'],MyDict['age']) = data.split(',')
>>> MyDict
{'name': '肖战', 'sex': '男', 'age': '28'}
>>> 

集合set
集合几乎所有的作用就是确保里边包含的元素的唯一性。

>>> num = {}
>>> type(num)
<class 'dict'>
>>> num1 = {1,2,3,3,4,4,4,5}
>>> type(num1)
<class 'set'>
>>> num1
{1, 2, 3, 4, 5}
>>> set1 = set([1,2,3,3,4,4,5])
>>> set1
{1, 2, 3, 4, 5}
>>> len(set1)     #len()函数可以确定集合元素个数            
5
>>> set1[0]      #会报错,因为集合是无序的,不支持索引
TypeError: 'set' object is not subscriptable
>>> num2 = {1,2,3,4,5}
>>> num2.add(6)
>>> num2.remove(1)
>>> num2
{2, 3, 4, 5, 6}
>>> #定义不可变集合frozenset()
>>>> num3 = frozenset({1,2,3,4,5})
>>> num3.add(6)
Traceback (most recent call last):
  File "", line 1, in <module>
    num3.add(6)
AttributeError: 'frozenset' object has no attribute 'add'
>>> 
>>> set1 = set([1,2])
>>> set1 = {[1,2]}
Traceback (most recent call last):
  File "", line 1, in <module>
    set1 = {[1,2]}
TypeError: unhashable type: 'list'
>>> set1 = {1,1.0,1.00}
>>> set1
{1}

从报错信息上可以看到“列表不是可哈希类型”。
利用哈希函数计算,相同的元素得到的哈希值(存放地址)是相同的,所以在集合中所有相同的元素都会覆盖掉,因此有了集合的唯一性。
通过哈希函数计算的地址不可能是按顺序排放的,所以集合才强调是无序的!
因为在Python的哈希函数会将相同的值的元素计算得到相同的地址,所以1和1.0是等值的。

如何将列表中的重复元素去掉??

>>> num1= [1,2,3,3,3,4,5,5,5]
>>> # method 1
>>> temp = []
>>> for each in num1:
	if each not in temp:
		temp.append(each)
>>> temp
[1, 2, 3, 4, 5]
>>> # method 2
>>> num1 = list(set(num1))
>>> num1
[1, 2, 3, 4, 5]

设计一个通讯簿的程序:

print("""|-----欢迎进入通讯录程序-----|
|----- 1:查询联系人资料 -----|
|----- 2:插入新的联系人 -----|
|----- 3:删除已有联系人 -----|
|----- 4:显示全部联系人 -----|
|----- 5:退出通讯录程序 -----|""")

phonebook = {'Jack':'11111111','Lucy':'22222222'}

while 1 :
    index = int(input("\n请输入相关的指令代码:"))
    if index < 1 or index > 5:
        index = int(input("请输入正确的指令代码:"))

    if index == 1:
        name = input("请输入联系人的姓名:")
        if name in phonebook.keys():
            print(name +' : '+ phonebook[name])
        else:
            print("用户不存在")
            
    if index == 2:
        name = input("请输入联系人的姓名:")
        if name in phonebook.keys():
            print("您输入的姓名在通讯录中已存在--->"+ name +' : '+ phonebook[name])
            flag = input("是否修改用户资料(yes/no):")
            if flag == 'yes':
                phonebook[name] = input("请输入用户联系电话:")
        else:
            phonebook[name] = input("请输入用户联系电话:")
            
    if index == 3:
        name  = input("输入想删除的联系人姓名:")
        if name in phonebook.keys():
            phonebook.pop(name)
        else:
            print("用户不存在")

    if index == 4:
        for each in phonebook:
            print(each + " : "+ phonebook[each])
                        
    if index == 5:
        print("|----- 感谢使用通讯录程序 -----|")
        break
 

运行结果如下:

|-----欢迎进入通讯录程序-----|
|----- 1:查询联系人资料 -----|
|----- 2:插入新的联系人 -----|
|----- 3:删除已有联系人 -----|
|----- 4:显示全部联系人 -----|
|----- 5:退出通讯录程序 -----|

请输入相关的指令代码:1
请输入联系人的姓名:Lucy
Lucy : 22222222

请输入相关的指令代码:2
请输入联系人的姓名:Lucy
您输入的姓名在通讯录中已存在--->Lucy : 22222222
是否修改用户资料(yes/no):yes
请输入用户联系电话:33333333

请输入相关的指令代码:4
Jack : 11111111
Lucy : 33333333

请输入相关的指令代码:2
请输入联系人的姓名:Tom
请输入用户联系电话:22222222

请输入相关的指令代码:4
Jack : 11111111
Lucy : 33333333
Tom : 22222222

请输入相关的指令代码:3
输入想删除的联系人姓名:Jack

请输入相关的指令代码:4
Lucy : 33333333
Tom : 22222222

请输入相关的指令代码:5
|----- 感谢使用通讯录程序 -----|

设计一个用户登录程序

def new_user():
    username = input("请输入用户名:")
    while True:
        if username in userinfo.keys():
            username = input("此用户名已经被使用,请重新输入:")
        else:
            break
    
    password = input("请输入密码: ")
    userinfo[username] = password
    print("注册成功!输入E/e立即登录!")

def user_enter():
    username = input("请输入用户名:")
    while True:
        if username not in userinfo.keys():
            username = input("用户不存在,请重新输入:")
        else:
            break

    password = input("请输入密码:")
    if password == userinfo[username]:
            print("欢迎进入系统!")
    else:
        print("密码错误!")
    
print("""
|-----新建用户:N/n-----|
|-----登录账号:E/e-----|
|-----推出程序:Q/q-----|""")

userinfo = dict()
while True:
    order = input("请输入指令代码:")
    while True:
        if order not in 'NnEeQq':
            order = input("输入指令有误,请重新输入:")
        else:
            break
    
    if order == 'N' or order == 'n':
        new_user()

    if order == 'E' or order == 'e':
        user_enter()
        
    if order == 'Q' or order == 'q':
        print("程序已经退出,谢谢使用")
        break

运行结果如下:

|-----新建用户:N/n-----|
|-----登录账号:E/e-----|
|-----推出程序:Q/q-----|
请输入指令代码:p
输入指令有误,请重新输入:n
请输入用户名:Jack
请输入密码: 123
注册成功!输入E/e立即登录!
请输入指令代码:n
请输入用户名:Jack
此用户名已经被使用,请重新输入:Lucy
请输入密码: 123
注册成功!输入E/e立即登录!
请输入指令代码:e
请输入用户名:Lucy
请输入密码:111
密码错误!
请输入指令代码:e
请输入用户名:Lucy
请输入密码:123
欢迎进入系统!
请输入指令代码:q
程序已经退出,谢谢使用
>>> 

你可能感兴趣的:(Python)