格式: [表达式 for 变量 in 旧列表] [表达式 for 变量 in 旧列表 if 条件]
names = ['tom', 'lily', 'abc', 'Hello', 'Jack', 'lucy'] result1 = [name for name in names if len(name) > 3] print(result1) # ['lily', 'Hello', 'Jack', 'lucy'] result2 = [name.capitalize() for name in names if len(name) <= 3] print(result2) # ['Tom', 'Abc'] # 将1-100之间被3整除的数字组成一个列表 result3 = [num for num in range(1, 101) if num % 3 == 0] print(result3) result4 = [num for num in range(1, 101) if num % 3 == 0 and num % 5 == 0] print(result4) # 0-5 偶数 0-10 奇数 (0,1) (0,3) ... (0,9) (2,1) (2,3) ... result5 = [(x, y) for x in range(5) if x % 2 == 0 for y in range(10) if y % 2 != 0] print(result5)
employee1 = {'name': 'zhangsan', 'salary': 4300} employee2 = {'name': 'lisi', 'salary': 5500} emp = [employee1, employee2] n = [employee['salary'] + 200 if employee['salary'] > 4500 else employee['salary'] + 500 for employee in emp] print(n) # [4800, 5700]
list1 = [1, 2, 3, 1, 5, 3, 2, 6, 8, 9, 8, 8, 9] set1 = {x - 1 for x in list1 if x > 5} # 类似列表推导式,没有重复元素 print(set1) # {8, 5, 7} dict1 = {'k1': 'v1', 'k2': 'v2'} newdict = {value: key for key, value in dict1.items()} print(newdict) # {'v1': 'k1', 'v2': 'k2'}
使用列表推导式生成列表,但受到内存限制,容量有限。 创建一个100万元素的列表,仅仅需要访问前面几个元素,造成空间浪费。
边循环边计算的机制,称为生成器, generator
next(generator): 每次调用都会产生一个新的元素,如果元素都产生完毕,再次调用会产生异常。
生成器方法: g.__next__() g.send(value)
list2 = [x * 3 for x in range(10)] print(type(list2)) # <class 'list'> g = (x * 3 for x in range(5)) print(type(g)) # <class 'generator'> print(g) # <generator object <genexpr> at 0x000000DC2790DF90> print(g.__next__()) # 0 print(g.__next__()) # 3 print(g.__next__()) # 6 print(next(g)) # 9 print(next(g)) # 12 #print(next(g)) # StopIteration
while True: try: e = next(g) print(e) except: print('没有元素啦') break print('测试结束') ''' 0 3 6 9 12 没有元素啦 测试结束 '''
# 定义生成器方式二: 函数 # 只要函数中出现yield关键字,则函数不再是函数,变成生成器了。 def func6(): n = 0 while True: n += 1 # print(n) yield n # 效果等同于 return n + 暂停 g = func6() print(g) # <generator object func6 at 0x0000008356E8DF20> print(next(g)) # 1 print(next(g)) # 2
使用生成器实现斐波那契数列:
def fib(length): a, b = 0, 1 n = 0 while n < length: yield b a, b = b, a + b n += 1 g = fib(8) print(next(g)) # 1 print(next(g)) # 1 print(next(g)) # 2 print(next(g)) # 3 print(next(g)) # 5 print(next(g)) # 8 print(next(g)) # 13 print(next(g)) # 21
def fib(length): a, b = 0, 1 n = 0 while n < length: print(b) a, b = b, a + b n += 1 fib(8) # 也能实现输出 1 1 2 3 5 8 13 21
def fib(length): a, b = 0, 1 n = 0 while n < length: yield b a, b = b, a + b n += 1 return 'abc' g = fib(8) print(next(g)) # 1 print(next(g)) # 1 print(next(g)) # 2 print(next(g)) # 3 print(next(g)) # 5 print(next(g)) # 8 print(next(g)) # 13 print(next(g)) # 21 print(next(g)) # StopIteration: abc ;没有 return时,报错StopIteration
def gen(): i = 0 while i < 5: temp = yield i print('temp: ', temp) i += 1 return '没有数据了' g = gen() print(g.__next__()) # 0 print(g.__next__()) # temp: None \n 1 print(g.__next__()) # temp: None \n 2 n1 = g.send('呵呵') print('n1: ', n1) # temp: 呵呵 \n n1: 3 n2 = g.send('哈哈') print('n2: ', n2) # temp: 哈哈 \n n2: 4 n3 = g.send(None) # temp: None \n StopIteration: 没有数据了, 取值时没有了报错,赋值成功 print('n3: ', n3) # 这个没有执行
直接往生成器非None传值报错
g = gen() # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) n1 = g.send('呵呵') # 报错: # TypeError: can't send non-None value to a just-started generator
g = gen() print(g.send(None)) # 改成 n = g.send(None) 也可以 n1 = g.send('呵呵') print('n1: ', n1) ''' 0 temp: 呵呵 n1: 1 '''
def gen1(): i = 0 while i < 5: temp = yield i print('temp: ', temp) for i in range(temp): print('------->', i) print('**************') i += 1 return '没有数据了' g1 = gen1() print(g1.send(None)) n1 = g1.send(3) print('n1:',n1) ''' 0 temp: 3 -------> 0 -------> 1 -------> 2 ************** n1: 3 ''' n2 = g1.send(4) print('n2:', n2) ''' temp: 4 -------> 0 -------> 1 -------> 2 -------> 3 ************** n2: 4 '''
def task1(n): for i in range(n): print('正在搬第{}块砖'.format(i+1)) yield None def task2(n): for i in range(n): print('正在听第{}首歌'.format(i+1)) yield None g1 = task1(3) g2 = task2(2) while True: g1.__next__() g2.__next__() ''' 正在搬第1块砖 正在听第1首歌 正在搬第2块砖 正在听第2首歌 正在搬第3块砖 Traceback (most recent call last): File "E:\PythonLearn\pythonBase\02door2\08-generator-03.py", line 23, in <module> g2.__next__() StopIteration '''
处理异常:
while True: try: g1.__next__() g2.__next__() except: pass
# 可迭代的对象 1. 生成器 2. 元祖 列表 集合 字典 字符串 # 如何判断一个对象是否可迭代 from collections import Iterable list1 = [1,2,46,5,3] result = isinstance(list1, Iterable) print(result) # True result = isinstance('abc', Iterable) print(result) # True result = isinstance(100, Iterable) print(result) # False
迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有元素都被访问完结束。迭代器只能往前不会后退。
# 可以被next()函数调用并返回下一个值的对象称为迭代器:Iterable。 # 可迭代的 不一定就是迭代器。 # 生成器是可迭代的,是迭代器。 list是可迭代的,但不是迭代器。 list1 = iter(list1) print(next(list1)) # 1 print(next(list1)) # 2