首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >列表理解:为每个项目返回两个(或更多)项目

列表理解:为每个项目返回两个(或更多)项目
EN

Stack Overflow用户
提问于 2012-08-09 00:27:53
回答 6查看 38K关注 0票数 104

是否可以为列表理解中的每个项目返回2个(或更多)项目?

我想要的(示例):

代码语言:javascript
复制
[f(x), g(x) for x in range(n)]

应返回[f(0), g(0), f(1), g(1), ..., f(n-1), g(n-1)]

因此,替换这段代码的内容如下:

代码语言:javascript
复制
result = list()
for x in range(n):
    result.add(f(x))
    result.add(g(x))
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-08-09 00:29:44

代码语言:javascript
复制
>>> from itertools import chain
>>> f = lambda x: x + 2
>>> g = lambda x: x ** 2
>>> list(chain.from_iterable((f(x), g(x)) for x in range(3)))
[2, 0, 3, 1, 4, 4]

计时:

代码语言:javascript
复制
from timeit import timeit

f = lambda x: x + 2
g = lambda x: x ** 2

def fg(x):
    yield f(x)
    yield g(x)

print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in range(3)))',
             setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2')

print timeit(stmt='list(chain.from_iterable(fg(x) for x in range(3)))',
             setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2')

print timeit(stmt='[func(x) for x in range(3) for func in (f, g)]',
             setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2')


print timeit(stmt='list(chain.from_iterable((f(x), g(x)) for x in xrange(10**6)))',
             setup='gc.enable(); from itertools import chain; f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

print timeit(stmt='list(chain.from_iterable(fg(x) for x in xrange(10**6)))',
             setup='gc.enable(); from itertools import chain; from __main__ import fg; f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

print timeit(stmt='[func(x) for x in xrange(10**6) for func in (f, g)]',
             setup='gc.enable(); f = lambda x: x + 2; g = lambda x: x ** 2',
             number=20)

2.69210777094

3.13900787874

1.62461071932

25.5944058287

29.2623711793

25.7211849286

票数 58
EN

Stack Overflow用户

发布于 2012-08-09 00:50:19

双重列表理解:

代码语言:javascript
复制
[f(x) for x in range(5) for f in (f1,f2)]

演示:

代码语言:javascript
复制
>>> f1 = lambda x: x
>>> f2 = lambda x: 10*x

>>> [f(x) for x in range(5) for f in (f1,f2)]
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]
票数 139
EN

Stack Overflow用户

发布于 2012-08-09 00:34:14

代码语言:javascript
复制
sum( ([f(x),g(x)] for x in range(n)), [] )

这相当于[f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...

你也可以把它想象成:

代码语言:javascript
复制
def flatten(list):
    ...

flatten( [f(x),g(x)] for x in ... )

注意:正确的方法是使用itertools.chain.from_iterable或双重列表理解。(它不需要在每个+上重新创建列表,因此具有O(N)性能,而不是O(N^2)性能。)当我想要一个快速的一行,或者我很着急,或者当组合的词条数量有限时(例如<= 10),我仍然会使用sum(..., [])。这就是为什么我仍然在这里提到它,但有这个警告。你也可以使用元组:((f(x),g(x)) for ...), () (或者根据卡奇克的评论,有一个生成器fg(x),它产生一个二元组)。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11868964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档