''' 用列表每个元素平方值构建另一份列表 a = [1, 2, 3, 4, 5, 6, 7, 8] ''' # 列表推导写法 squares = [x ** 2for x in a] # map写法 squares = map(lamda x: x ** 2, a)
# 条件输出 # 列表推导输出偶数 squares = [x for x in a if a%2 == 0] # map辅以filter输出偶数 squares = map(lambda x: x, filter(lambda x: x % 2 == 0, a))
字典与集也有类似的推导机制,编写算法时,可以通过这些推导机制来创建衍生的数据结构。
1 2 3 4 5 6 7 8 9
chile_ranks = {'ghost': 1, 'god': 2, 'man': 3} rank_dict = {rank: name for name,rank in chile_ranks.items()} chile_len_set = {len(name) for name in rank_dict.values()} print(rank_dict) print(chile_len_set)
''' eg. 读取日志文件 ''' it = (len(x) for x inopen('/var/log.log')) print(it) >>> <generator object <genexpr> at 0x101b81480 print(next(it)) >>> "logs"
要点
当输入数据量较大时,列表推导可能会因为占用太多内存而出现问题
由生成器表达式返回的迭代器,可以逐次产生输出值,从而避免内存用量问题
把某个生成器表达式所返回的迭代器,放在另一个生成器表达式的for子表达式中,即可将二者结合起来
1 2
a = [1, 2, 3, 4, 5, 6] res = ((x, x ** 2) for x in a)
串在一起的生成器表达式执行速度很快
尽量用enumerate取代range
1 2 3 4 5 6 7 8 9 10
''' 场景说明:当想同时打印元素在列表中的索引和值的时候,使用range略显生硬 ''' # range写法 for i range(len(list)): value = list[i] index = i # enumerate写法 for i, value inenumerate(list): print('%d: %s' % (i + 1, value))
要点
尽量使用enumerate来改写那种将range与下标访问结合的序列遍历代码
可以给enumerate提供第二个参数, 以指定开始计数时所用的值
用zip函数同时遍历两个迭代器
zip可以将两个或者多个迭代器封装成一个生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
''' 场景说明:需要平行对两个列表进行操作时 ''' names = ['alice', 'bob', 'cendy'] letters = [len(n) for n in names]
longest_name = None max_letters = 0
for name, count inzip(names, letters): if count > max_letters: longest_name = name max_letters = count print(longest_name)