python进阶学习(2)--列表推导和生成器表达式

列表推导

列表推导(list comprehesion)可以从可迭代类型中的元素过滤或加工,构建出一个序列。

不用列表推导:

>>> symbols = 'abc123'
>>> codes = []
>>> for symbol in symbols:
...     codes.append(ord(symbol))
...
>>> codes
[97, 98, 99, 49, 50, 51]

用列表推导:

>>> symbols = 'abc123'
>>> codes = [ord(symbol) for symbol in symbols]
>>> codes
[97, 98, 99, 49, 50, 51]

还可以用来生成两个或以上的可迭代类型的笛卡尔积,即两层或多层 for 循环的列表推导。

两层 for 循环的列表推导:

>>> colors = ['black', 'white']
>>> sizes = ['S', 'M', 'L']
>>> tshirts = [(color, size) for color in colors for size in sizes]
>>> tshirts
[('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]

相当于:

>>> for color in colors:
...     for size in sizes:
...             print((color, size))
...
('black', 'S')
('black', 'M')
('black', 'L')
('white', 'S')
('white', 'M')
('white', 'L')

需要注意的是,列表推导的前一个 for 循环就是外层 for 循环,后一个 for 循环就是内层 for 循环。

另外,python3.x 就不存在变量泄露的问题,列表推导内部的变量是局部的,仅限于列表推导内,同时也可以引用上下文的同名变量:

# python3.9
>>> x = 'ABC'
>>> dummy = [ord(x) for x in x]
>>> x
'ABC'

可以看到 x 变量并没有改变,如果是在 python2.x 中,它的值就被改变为 'C'。

# python2.7
>>> x = 'ABC'
>>> dummy = [ord(x) for x in x]
>>> x
'C'

使用列表推导的最大好处就是可读性更高。因此,一般建议两层 for 循环内使用列表推导

生成器表达式

生成器表达式的语法跟列表推导类似,不同的是表达式外面用括号。但是,本质上的不同是生成器表达式遵守迭代器协议,逐个地产出元素,而不是一次性产出一个所有的数据,而列表推导先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。

总的来说就是,生成器表达式比列表推导更节省内存。

>>> symbols = 'abc132'
>>> tuple(ord(symbol) for symbol in symbols)            # 1
(97, 98, 99, 49, 51, 50)
>>>
>>> import array
>>> array.array('I', (ord(symbol) for symbol in symbols))   # 2
array('I', [97L, 98L, 99L, 49L, 51L, 50L])

如果生成器表达式是函数调用过程的唯一参数,那么可以省略外层的括号。

下面的例子比较,可以看出生成器表达式是在每次执行 for 循环时,才产出一个元素。

>>> s = 'apple'
>>> t = (ord(s) for s in s)
>>> for a in t:
...     print(a)
...
97
112
112
108
101
>>> for a in t:
...     print(a)
...
>>>

t 是一个生成器,第一次执行 for 循环遍历后,可以逐个输出 s 的字符,但是第二次执行 for 循环时,生成器 t 已经产生所有的元素,相当于指针已经指向 s 的末尾,就不再有元素产出,所以什么元素都没有输出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值