相关疑难解决方法(0)

列表推导和生成器表达式中的yield

以下行为对我来说似乎有点违反直觉(Python 3.4):

>>> [(yield i) for i in range(3)]
<generator object <listcomp> at 0x0245C148>
>>> list([(yield i) for i in range(3)])
[0, 1, 2]
>>> list((yield i) for i in range(3))
[0, None, 1, None, 2, None]
Run Code Online (Sandbox Code Playgroud)

最后一行的中间值实际上并不总是None,它们是我们send进入生成器的任何东西,等价(我猜)到下面的生成器:

def f():
   for i in range(3):
      yield (yield i)
Run Code Online (Sandbox Code Playgroud)

令我感到有趣的是,这三条线路都很有用.该参考指出,yield仅在一个函数定义允许的(虽然我可能读错和/或它可能只是已经从旧版本复制).前两行在SyntaxErrorPython 2.7中生成,但第三行不生成.

而且,这似乎很奇怪

  • 列表推导返回生成器而不是列表
  • 并且生成器表达式转换为列表,相应的列表推导包含不同的值.

有人可以提供更多信息吗?

python yield list-comprehension generator generator-expression

70
推荐指数
1
解决办法
9589
查看次数

为什么itertools.chain比扁平化列表理解更快?

这个问题的评论中讨论的上下文中提到,虽然连接一串字符串只是简单地''.join([str1, str2, ...])连接,但连接一系列列表就像是list(itertools.chain(lst1, lst2, ...)),尽管你也可以使用列表理解[x for y in [lst1, lst2, ...] for x in y].让我感到惊讶的是,第一种方法始终比第二种方法更快:

import random
import itertools

random.seed(100)
lsts = [[1] * random.randint(100, 1000) for i in range(1000)]

%timeit [x for y in lsts for x in y]
# 39.3 ms ± 436 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit list(itertools.chain.from_iterable(lsts))
# 30.6 ms ± 866 µs per loop (mean ± std. dev. …
Run Code Online (Sandbox Code Playgroud)

python list-comprehension flatten python-itertools

12
推荐指数
1
解决办法
1127
查看次数