简介
列表推导式是构建列表的快捷方式,而生成器表达式则是可以用来创建其他任何类型的序列。
列表推导式
列表推导和可读性
比较下使用for循环和列表推导式生成一个列表
"""
列表推导式更具可读性
"""
def str_to_unicode(symbols="adb&"):
"""
把一个字符串变成Unicode码位的列表
使用for循环
:param symbols:
:return:
"""
codes = []
for symbol in symbols:
codes.append(ord(symbol))
return codes
def str_to_unicode_another(symbols="adb&"):
"""
把一个字符串变成Unicode码位的列表
使用列表推导式
:param symbols:
:return:
"""
codes = [ord(symbol) for symbol in symbols]
return codes
if __name__ == '__main__':
print(str_to_unicode())
print(str_to_unicode_another())
"""
结果:
[97, 100, 98, 38]
[97, 100, 98, 38]
"""
可见列表推导式更具可读性,但是如果列表推导式超过两行,你就要考虑是不是得用for循环重写了。
列表推导同filter和map的比较
列表推导式可以帮我们把一个序列 或者其他可迭代类型中的元素过滤或者加工,然后生成一个新列表。Python内置的高阶函数filter和map组合起来也能达到这一效果,但是在可读性上却打了不少折扣。
def map_filter(symbols="adb&"):
"""
用列表推导式和map/filter组合创建同样的的列表
:param symbols:
:return:
"""
# 列表推导式
res = [ord(symbol) for symbol in symbols if ord(symbol) > 90]
# map/filter
res_map = list(filter(lambda a: a > 90, map(ord, symbols)))
return res, res_map
if __name__ == '__main__':
print(map_filter())
"""
([97, 100, 98], [97, 100, 98])
"""
生成器表达式
虽然列表推导式也可以初始化元组、数组或者其它序列,但是生成器表达式是更好的选择。
这是因为生成器表达式背后遵循了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递给某个构造器函数里。可以极大地节省内存。
生成器表达式的语法和列表推导差不多,只是把中括号换成圆括号。
def generator(symbols="adb&"):
"""
使用生成器表达式初始化元组和数组
:param symbols:
:return:
"""
t = tuple(ord(symbol) for symbol in symbols) #如果生成器表达式是函数的唯一参数,则不需要用括号把它围起来
a = array.array('I', (ord(symbol) for symbol in symbols))
return t, a
if __name__ == '__main__':
print(generator())
"""
((97, 100, 98, 38), array('I', [97, 100, 98, 38]))
"""