112

リスト内包内のアイテムごとに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))
4

7 に答える 7

151

ダブルリスト内包表記:

[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]
于 2012-08-08T16:50:19.243 に答える
60
>>> 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

于 2012-08-08T16:29:44.073 に答える
14
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 ^ 2)のパフォーマンスではなくO(N)のパフォーマンスが得られます。)sum(..., [])簡単なワンライナーが必要な場合や急いでいる場合でも使用します。 、または結合される用語の数が制限されている場合(たとえば、<= 10)。そのため、この警告とともに、ここでまだ言及します。タプルを使用することもできます:(((f(x),g(x)) for ...), ()またはkhachikのコメントによると、2つのタプルを生成するジェネレータfg(x)があります)。

于 2012-08-08T16:34:14.073 に答える
4

OPがリスト内包表記ソリューションを探していることは知っていますが、を使用して別の方法を提供したいと思いlist.extend()ます。

f = lambda x: x
g = lambda x: 10*x

result = []
extend = result.extend
for x in range(5):
    extend((f(x),g(x)))

これは、二重リスト内包を使用するよりもわずかに高速です。

nums = range(100000)

def double_comprehension():
    return [func(x) for x in nums for func in (f,g)]

def list_extend():
    result = []
    extend = result.extend
    for x in nums:
        extend((f(x),g(x)))
    return result

%timeit -n100 double_comprehension()
23.4 ms ± 67 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit -n100 list_extend()
20.5 ms ± 213 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

Pythonバージョン:3.8.0

于 2020-07-04T04:38:31.520 に答える
2

このラムダ関数は、2つのリストを1つのリストに圧縮します。

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]
于 2015-11-26T16:15:10.620 に答える
0

reduceを使用したソリューション:

from functools import reduce

f    = lambda x: f"f({x})" ## Just for example
g    = lambda x: f"g({x})"
data = [1, 2, 3]

reduce(lambda acc, x: acc + [f(x), g(x)], data, [])
# => ['f(1)', 'g(1)', 'f(2)', 'g(2)', 'f(3)', 'g(3)']

これは、問題に取り組むための機能的な方法です。リスト内包表記は、基本的mapにデータを調べる別の方法ですが、このように入力と出力の間でマッピングが1対1でない場合はreduce、出力を生成する方法に多少の余裕があります。

一般にfor、フォームの実装は次のとおりです。

result = []
for n in some_data:
  result += some_operation()
  ## etc.

(つまり、リストまたは同様のデータ構造、アキュムレータパターンに副作用をもたらすことを目的としたforループ)

map/reduce/filter宣言型の実装にリファクタリングできます。

于 2020-09-24T21:10:03.277 に答える
-2

良さ、悲しみ!なぜこれらすべてのラムダ、フラット、ジップ、合計がありますか?これは最も単純で読みやすいものではありませんか:

>>> [v
...  for x in range(5)
...      for v in (2 * x,
...                2 * x + 1)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>

f(x)(最後の2つの式をand g(x)、またはなどに置き換えます。)

于 2021-03-26T18:01:50.873 に答える