蟒蛇(列表理解):返回两个(或更多)的项目每个项目(Python (List Comprehensi

2019-06-26 21:05发布

是否有可能在一个列表理解返回2(或更多)的项目每个项目?

我想(例如):

[f(x), g(x) for x in range(n)]

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

所以,东西来取代这个代码块:

result = list()
for x in range(n):
    result.add(f(x))
    result.add(g(x))

Answer 1:

>>> 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]

时序:

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



Answer 2:

双榜理解:

[f(x) for x in range(5) for f in (f1,f2)]

演示:

>>> 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]


Answer 3:

sum( ([f(x),g(x)] for x in range(n)), [] )

这等同于[f(1),g(1)] + [f(2),g(2)] + [f(3),g(3)] + ...

你也可以把它当做:

def flatten(list):
    ...

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

注意:正确的方法是使用itertools.chain.from_iterable或双榜理解。 (它不需要重新创建每个+列表,因而具有O(N)的性能,而不是O(N ^ 2)的性能。)我还是会使用sum(..., [])时,我想一个快速-liner或我赶时间,或者当被组合的项数是有界的(例如,<= 10)。 这就是为什么我仍然在这里提到它,用这个警告。 您还可以使用元组: ((f(x),g(x)) for ...), ()或每khachik的评论,具有发电机FG(X)这产生了两元组)。



Answer 4:

这个lambda表达式拉链两个列表成为一个单一的一个:

zipped = lambda L1, L2: [L[i] 
                         for i in range(min(len(L1), len(L2))) 
                         for L in (L1, L2)]

例:

>>> f = [x for x in range(5)]
>>> g = [x*10 for x in range(5)]
>>> zipped(f, g)
[0, 0, 1, 10, 2, 20, 3, 30, 4, 40]


文章来源: Python (List Comprehension): Returning two (or more) items for each item