3

次の何が問題になっていますか?:

lss = reduce(list.extend, [[1],[2]], [])

原因:

Traceback (most recent call last):
  File "<pyshell#230>", line 1, in <module>
    lss = reduce(list.extend, [[1],[2]], [])
TypeError: descriptor 'extend' requires a 'list' object but received a 'NoneType'

NoneTypeがどこから来ているのかわかりません。

4

4 に答える 4

14

代わりにこれを試してください:

lss = reduce(lambda acc, ele : acc + ele, [[1],[2]], [])

lss
> [1, 2]

問題は、それextend()が返されることですNone(そこNoneTypeから が来ています)、そしてそれはあなたがやりたいことで動作しません - に渡された関数は値を返す必要があります: これまでの累積結果です。reduce()

于 2012-07-04T15:30:06.523 に答える
8

私はそれが注目に値すると思います:

sum([[1],[2]], [])

また、動作し、ラムダを渡して削減するよりも高速になると確信しています。

さまざまな方法の速度に興味があったので、いくつかのテストを行いました。

reduce(lambda a,b:a+b, x, [])               3644.38161492
reduce(list.__add__, x, [])                 3609.44079709
sum(x,[])                                   3526.84987307
y = [];for z in x: y.extend(z)               143.370306969
y = [];map(y.extend,x)                        71.7020270824
y = [None]*400;del y[:];map(y.extend,x)       66.2245891094
list(itertools.chain(*x))                    102.285979986
list(itertools.chain.from_iterable(x))        96.6231369972
[a for b in x for a in b]                    203.764872074

そしてPyPyで(なぜなら、なぜそうではないのか)

reduce(lambda a,b:a+b, x, [])               4797.5895648
reduce(list.__add__, x, [])                 4794.01214004
sum(x,[])                                   4748.02929902
y = [];for z in x: y.extend(z)                56.9253079891
y = [];map(y.extend,x)                        73.8642170429
y = [None]*400;del y[:];map(y.extend,x)      152.157783031
list(itertools.chain(*x))                    633.854824066
list(itertools.chain.from_iterable(x))       629.917827129
[a for b in x for a in b]                     89.6922459602

x = [[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[5,6,7,8],[6,7,8,9],[7,8,9,10],[8,9,10,11]]*100

結論:

  1. リデュースでラムダを使用すると時間がかかります
  2. 特殊なsum機能はより速く、次に削減します
  3. リストの追加には時間がかかります。
  4. Pythonループのオーバーヘッドは重要です。
于 2012-07-04T15:35:15.097 に答える
1

Óscar López が指摘したように、 をlist.extend返すNoneため、 では使用できませんreducelambda関数の推奨される使用方法の代わりに、次のように使用list.__add__することもできreduceます。

>>> reduce(list.__add__, [[1],[2]], [])
[1, 2]
于 2012-07-04T15:53:59.760 に答える
1

itertools.chainを使用することをお勧めします

最初の iterable からすべての iterable が使い果たされるまで要素を返し、次にすべての iterable が使い果たされるまで次の iterable に進む反復子を作成します。連続したシーケンスを単一のシーケンスとして扱うために使用されます。に相当:

def chain(*iterables):
    # chain('ABC', 'DEF') --> A B C D E F
    for it in iterables:
        for element in it:
            yield element
于 2012-07-04T16:06:20.327 に答える