三元表达式
# what:就是简写if...else...结构,且都只有一条语句 # 语法:结果1 if 条件 else 结果2 # 注意:结果1|2不一定要与条件有必然关系,条件只是选择结果1或结果2的判断依据 # 案例:获得两个数中的大值 | 小者 n1 = int(input('n1: ')) n2 = int(input('n2: ')) res = n1 if n1 > n2 else n2 print(res) res = n2 if n1 > n2 else n1 print(res)
列表字典推导式
# 列表推导式 # 语法:[结果 for 结果 in 可for循环操作的对象] # 案例:[v for v in 'abc'] => ['a', 'b', 'c'] # 产生1~10之间的偶数list => [2, 4, 6, 8, 10] ls = [i for i in range(2, 11, 2)] # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(ls) # 1~5之间的数用奇数偶数形参list => ['奇数', '偶数', '奇数', '偶数','奇数'] ls = ['奇数' if i % 2 != 0 else '偶数' for i in range(1, 6)] print(ls) ls = ('奇数' if i % 2 != 0 else '偶数' for i in range(1, 6)) print(tuple(ls)) #字典推导式 # 语法:{k: v for k, v in 可for循环操作的对象(每一次循环的结果可以被解压为两个值)} # 案例: # 原数据: [('a', 1), ('b', 2)] => {'a': 1, 'b': 2} source = [('a', 1), ('b', 2)] dic = {k: v for k, v in source} print(dic) dic = {i: 0 for i in 'abc'} print(dic) #print({}.fromkeys('abc', 0))
迭代器
# 寻求一种不依赖索引,且可以循环取值的方式 dic = {'a': 1, 'b': 2, 'c': 3} print(dic) # {'a': 1, 'b': 2, 'c': 3} # 通过__iter__()方法获取dic的一个不用依赖索引的取值容器 box = dic.__iter__() print(box) #<dict_keyiterator object at 0x0000000001D9D4A8> print(box.__next__()) #a box3 = 'abc'.__iter__() print(box3) # <str_iterator object at 0x0000000001E7CBA8> print(box3.__next__()) # a box4 = {'a', 'b', 'c'}.__iter__() print(box4) # <set_iterator object at 0x0000000001EBA708> print(box4.__next__()) # a print(box4.__next__()) # b ''' 1.txt内容: 11111111 22222222 33333333 44444444 ''' with open('1.txt', 'r', encoding='utf-8') as r: print(r) # <_io.TextIOWrapper name='1.txt' mode='r' encoding='utf-8'> print(r.__next__()) # 11111111 print(r.__next__()) # 22222222
# 可迭代对象
# 有__iter__()方法的对象都称之为 可迭代对象 # 可迭代对象:可以被转化为不依赖索引取值的容器,这样的对象就叫做可迭代对象 # -- 对象.__iter__() 来生成不依赖索引取值的容器 # -- 结论:有__iter__()方法的对象都称之为 可迭代对象 # 可迭代对象.__iter__() => 和该对象有关系的迭代器对象 dict_keyiterator object box = dic.__iter__() # 可迭代对象有哪些:str | list | tuple | set | dict | range() | enumerate() | file | 生成器对象
# 迭代器对象:
# 有__next__()且可以通过__next__()进行取值的容器 # 迭代器对象:可以通过__next__()的方式进行取值的容器,且取一个少一个 # -- 结论:有__next__()且可以通过__next__()进行取值的容器 # -- 注意:迭代器对象自身也拥有__iter__(), 通过该方法返回的是迭代器对象自身 res = box.__next__() # 从迭代器对象(容器)取出值,取一个少一个 box = box.__iter__() # 迭代器对象.__iter__()得到迭代器对象本身 # 迭代器对象有哪些:enumerate() | file | 生成器对象
# 迭代器(for循环):就是用来从可迭代对象中进行取值的循环方法 | 语法:for 变量 in 对象:
# -- 1.通过对象.__iter__()获取其对应的迭代器对象 # -- for可以操作迭代器对象及可迭代对象,统一写法,所以迭代器和可迭代对象都有__iter__() # -- 2.在内部通过迭代器对象的__next__()进行取值,将值赋值给 语法中的变量,取一个少一个 # -- 3.当迭代器对象取完了,在内部自动捕获异常,并结束循环取值 dic1 = {'a': 1, 'b': 2, 'c': 3} # dic是可迭代对象 dic1_box = dic1.__iter__() # 通过__iter__()得到的是迭代器对象 # print(len(dic1_box)) # 迭代器对象没有len()方法 while True: try: print(dic1_box.__next__()) except StopIteration: #捕捉报错,并退出 print('取完了') break for v in dic1: print(v)
生成器
# 生成器:自定义的迭代器对象 def fn(): print(1) yield 666 print(2) yield 888 print(3) obj = fn() # generator object => [666, 888] # print(obj) # <generator object fn at 0x0000000001E24C50> # 去生成器中执行代码,拿到遇到的第一个yield后面的值,并停止运行 print(obj.__next__()) # 1 666 # 再接着上一个yield,再进行往下执行代码,再拿到下一个个yield后面的值,并停止运行 print(obj.__next__()) # 2 888 # 重复上面的过程,如果没有遇到yield,就报错 print(obj.__next__()) # StopIteration # 举例
#1、示例:生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性 >>> chicken=('鸡蛋%s' %i for i in range(5)) >>> chicken <generator object <genexpr> at 0x10143f200> >>> next(chicken) '鸡蛋0' >>> list(chicken) #因chicken可迭代,因而可以转成列表 ['鸡蛋1', '鸡蛋2', '鸡蛋3', '鸡蛋4',] #2、优点:省内存,一次只产生一个值在内存中
# 将传入的值扩大两倍返回 def fn1(a, b, c): yield a * 2 yield b * 2 yield c * 2 # 解决方案 def fn1(*args): i = 0 while i < len(args): yield args[i] * 2 i += 1 for v in fn1(10, 20, 30, 40, 50): print(v) # 依次获取阶乘 1! 2! 3! ... def fn2(): total = 1 count = 1 while True: total *= count yield total count += 1 obj = fn2()
print(obj.__next__()) # 1!=1
print(obj.__next__()) # 2!=2
print(obj.__next__()) # 3!=6
print(obj.__next__()) # 4!=24
了了解
def fn3(): msg = yield 1 print(msg) yield 2 obj3 = fn3() print(obj3.__next__()) # 1.send会为当前停止的yield传入参数,内部可以通过yield来接收传入的参数 # 2.send自身也会调用__next__()去获取下一个yield的结果 result = obj3.send('ooo') print(result)
举例:
def fn4(peoples): count = 0 print('%s在面试' % peoples[count]) while count < len(peoples): name = yield peoples[count] count += 1 print(name + "叫来%s来面试" % peoples[count]) peoples = ['张三', '李四', '王五'] obj4 = fn4(peoples) name = obj4.send(None) # 第一次没有yield接收值,所以只能调__next__(),或是send(None) print(name + '面试完毕') while True: try: name = obj4.send(name) print(name + '面试完毕') except Exception: print('所有人面试完毕') break
枚举对象
# 枚举对象:为迭代器对象产生迭代索引 ls = [3, 1, 2, 5, 4] list(enumerate(ls)) # => [(0, 3), (1, 1), (2, 2), (3, 5), (4, 4)] dic = {'a': 100, 'b': 200} print(list(enumerate(dic))) # => [(0, 'a'), (1, 'b')]
递归
# 递归:函数直接或间接调用自己 # 回溯:找寻答案的过程 # 递推:通过最终的值反向一步步推出最初需要的结果 # 前提: # 1.递归条件是有规律的 # 2.递归必须有出口
import sys
print(sys.getrecursionlimit()) # 最大递归层 1000
sys.setrecursionlimit(100) #可以修改最大递归次数
# 举例 # 拿递归求得年纪 def get_age(num): if num == 1: return 58 age = get_age(num - 1) - 2 return age age = get_age(10) print(age) # 传入一个num,求得该num的阶乘 # 5! = 5 * 4 * 3 * 2 * 1 = 5 * 4! # 4! = 4 * 3 * 2 * 1 = 4 * 3! # 3! = 3 * 2 * 1 = 3 * 2! # 2! = 2 * 1 = 2 * 1! # 1! = 1 def get_total(num): if num == 1 or num == 0: return 1 total = num * get_total(num - 1) # 3 * 2! => 2 * 1!1 => 1 => 2 * 1 return total print(get_total(3))
匿名函数
# 匿名函数:没有名字的函数 # 1.用lambda声明匿名函数 # 2.没有函数名,lambda与:之间一定是参数列表,参数列表省略(),且支持所有参数语法 # 3.匿名函数没有函数体,只有返回值,所有省略了return,且返回值只能有一个 # -- (不能将多个返回值自动格式化为元组)
# lambda 参数1, ..., 参数n: 一个返回值
# 应用场景 # 1.用一个变量接收,该变量就充当与函数的名字 - 不常见 func = lambda x, y: (x + y, x - y) print(func(10, 20)) # 2.结合内置函数来使用 y=(max([1, 2, 6, 5, 3], key=lambda x: x)) print(y) # 6 dic = { 'Bob': (1, 88888), 'Ben': (2, 300000), 'Tom': (3, 99999) } s = min(dic, key=lambda k: dic[k][1]) # 按薪资求最小值 print(s) #Bob
内置函数
官方3.7.3列出内置函数:https://docs.python.org/zh-cn/3/library/functions.html
# 已见过的 # 1.类型转换:int() tuple() # 2.常规使用:print() input() len() next() iter() open() range() enumerate() id() # 3.进制转换:bin() oct() hex() 将10进制转换为2 | 8 | 16进制 print(bin(10)) # 0b1010 print(oct(10)) # 0o12 print(hex(10)) # 0xa # 3.运算:abs() print(abs(-1)) # 绝对值 print(chr(9326)) # 将ASCII转换为字符 print(ord('①')) # 逆运算 print(pow(2, 3)) # 2的3次方 print(pow(2, 3, 3)) # 2的3次方对3求余 print(sum([1, 2, 3])) # 求和 # 4.反射:getattr() delattr() hasattr() setattr() # 5.面向对象的相关方法:super() staticmethod() classmethod() def fn():pass print(callable(fn)) # 对象能不能被调用 # 6.原义字符串 print('a\nb') s = ascii('a\nb') print(s) s = repr('a\nb') print(s) print(r'a\nb') print(all([1, 0, 0])) print(any([0, 0, 1])) # compile() exec() eval()
# max的工作原理 # 1.max要去遍历所有求大值的数据,这些一一被遍历出来的数要被依次传入key=fn的fn中 # -- fn必须有参数,且只有一个参数,就是当前被遍历出来的被比较的数据 # 2.max再根据fn的返回值决定比较大小的依据 dic = { 'owen': (1, 88888), 'egon': (2, 300000), 'liuXX': (3, 99999) } def fn2(k): # return k # 求名字最大 # return dic[k][0] # 求工号最大 return dic[k][1] # 求薪资最大 max_p = max(dic, key=fn2) print(max_p) # egon # min函数的工作原理 # 1.min要去遍历所有求小值的数据,这些一一被遍历出来的数要被依次传入key=fn的fn中 # -- fn必须有参数,且只有一个参数,就是当前被遍历出来的被比较的数据 # 2.min再根据fn的返回值决定比较大小的依据 dic = { 'owen': (1, 88888), 'egon': (2, 300000), 'liuXX': (3, 99999) } res = min(dic, key=lambda x: dic[x][1]) print(res) # 排序:sorted dic = { 'owen': (1, 88888), 'egon': (2, 300000), 'liuXX': (3, 99999) } # 总结:排序的可迭代对象,排序的规则,是否反转 res = sorted(dic, key=lambda k: dic[k][1], reverse=True) # 按薪资排序的人名list for k in res: print(k, dic[k][1]) # map:映射 - 格式化每一次的遍历结果 names = ['Owen', 'Egon', 'Liuxx'] def fn(x): # print(x) # 将所有名字全小写 return x.lower() res = map(fn, names) print(list(res)) dic1 = { 'owen': 88888, 'egon': 300000, 'liuXX': 99999 } def fn1(x): dic1[x] += 1 return 10000 # 总结:遍历第二个参数(可迭代对象),将遍历的结果丢给第一个函数, # 函数有一个参数,就是一一遍历的值 # map的作用(返回值):在当前数据基础上改变值(可以任意修改) res = map(fn1, dic1) print(list(res)) print(dic1) # 合并:reduce from functools import reduce # 求[1, 3, 4, 2, 10]所有元素的总和 res = reduce(lambda x, y: x + y, [1, 3, 4, 2, 10]) print(res)
练习:
1、文件内容如下,标题为:姓名,性别,年纪,薪资 egon male 18 3000 alex male 38 30000 wupeiqi female 28 20000 yuanhao female 28 10000 要求: 从文件中取出每一条记录放入列表中, 列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式 2 根据1得到的列表,取出薪资最高的人的信息 3 根据1得到的列表,取出最年轻的人的信息 4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式 5 根据1得到的列表,过滤掉名字以a开头的人的信息 6 使用递归打印斐波那契数列(前两个数的和得到第三个数,如:0 1 1 2 3 4 7...) 7 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
#1 with open('db.txt') as f: items=(line.split() for line in f) info=[{'name':name,'sex':sex,'age':age,'salary':salary} \ for name,sex,age,salary in items] print(info) #2 print(max(info,key=lambda dic:dic['salary'])) #3 print(min(info,key=lambda dic:dic['age'])) # 4 info_new=map(lambda item:{'name':item['name'].capitalize(), 'sex':item['sex'], 'age':item['age'], 'salary':item['salary']},info) print(list(info_new)) #5 g=filter(lambda item:item['name'].startswith('a'),info) print(list(g)) #6 #非递归 def fib(n): a,b=0,1 while a < n: print(a,end=' ') a,b=b,a+b print() fib(10) #递归 def fib(a,b,stop): if a > stop: return print(a,end=' ') fib(b,a+b,stop) fib(0,1,10) #7 l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]] def get(seq): for item in seq: if type(item) is list: get(item) else: print(item) get(l)