ネストされたリストの理解をリスト化しますか?


219

私はこのネストされたリストを持っています:

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

次に、リストの各要素を浮動小数点に変換します。私の解決策はこれです:

newList = []
for x in l:
  for y in x:
    newList.append(float(y))

しかし、これはネストされたリスト内包表記を使用して行うことができますか?

私がやったことは:

[float(y) for y in x for x in l]

しかし、結果は2400の合計で100の束になります。

どんな解決策でも、説明をいただければ幸いです。ありがとう!


15
あなたは、くださいまた、あなたのリストを平らにしたいですか?
グレッグ・ヒューギル2013

@GregHewgill:OPは返答しませんでしたが、彼らが受け入れた回答に基づいて、ネストをそのままにしたかったようです。
smci 2018

回答:


317

ネストされたリスト内包でこれを行う方法は次のとおりです。

[[float(y) for y in x] for x in l]

これにより、リストのリストが表示されます。文字列の代わりに浮動小数点を使用する以外は、最初のリストと同じです。1つのフラットリストが必要な場合は、を使用します[float(y) for x in l for y in x]


190

ネストされたforループをネストされたリスト内包に変換する方法は次のとおりです。

ここに画像の説明を入力してください

ネストされたリスト内包がどのように機能するかを次に示します。

            l a b c d e f
                  
In [1]: l = [ [ [ [ [ [ 1 ] ] ] ] ] ]
In [2]: for a in l:
   ...:     for b in a:
   ...:         for c in b:
   ...:             for d in c:
   ...:                 for e in d:
   ...:                     for f in e:
   ...:                         print(float(f))
   ...:                         
1.0

In [3]: [float(f)
         for a in l
   ...:     for b in a
   ...:         for c in b
   ...:             for d in c
   ...:                 for e in d
   ...:                     for f in e]
Out[3]: [1.0]

あなたの場合、それはこのようなものになります。

In [4]: new_list = [float(y) for x in l for y in x]

21
超便利!ループ(上から下)がジェネレーターで左から右に並べられていることを明確にします。(f(x) for x in l)forループの2行目が左側に配置されているため、これは明らかではありません。
user48956 2018年

これは実際に私と一緒に家にぶつかっている説明のようです、ありがとう!
ダグラスプラムリー

48
>>> l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]
>>> new_list = [float(x) for xs in l for x in xs]
>>> new_list
[40.0, 20.0, 10.0, 30.0, 20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0, 30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0]

42

目的の出力が何であるかはわかりませんが、リスト内包表記を使用している場合、順序はネストされたループの順序に従います。だから私はあなたが望むものを手に入れました:

[float(y) for x in l for y in x]

原則は、ネストされたforループとして書き出すときに使用するのと同じ順序を使用することです。


これは、答えなければなりませんいくつかの時間として、我々は、角ブラケットにiteratoolたくない
zinking

1
ネストされていないリストを出力するため、これは正しい答えではない可能性がありますが、私が探していたもの、特に原則です。ありがとう!
ロドリゴE.プリンシペ

4

私はここで少し遅れていますが、実際にリスト内包がどのように機能するか、特にネストされたリスト内包がどのように機能するかを共有したかったので:

New_list= [[float(y) for x in l]

実際には次と同じです:

New_list=[]
for x in l:
    New_list.append(x)

そして今ネストされたリスト内包:

[[float(y) for y in x] for x in l]

と同じです。

new_list=[]
for x in l:
    sub_list=[]
    for y in x:
        sub_list.append(float(y))

    new_list.append(sub_list)

print(new_list)

出力:

[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]

3

ネストされたリスト内包表記が気に入らない場合は、map関数も使用できます。

>>> from pprint import pprint

>>> l = l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']] 

>>> pprint(l)
[['40', '20', '10', '30'],
['20', '20', '20', '20', '20', '30', '20'],
['30', '20', '30', '50', '10', '30', '20', '20', '20'],
['100', '100'],
['100', '100', '100', '100', '100'],
['100', '100', '100', '100']]

>>> float_l = [map(float, nested_list) for nested_list in l]

>>> pprint(float_l)
[[40.0, 20.0, 10.0, 30.0],
[20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0],
[30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0],
[100.0, 100.0],
[100.0, 100.0, 100.0, 100.0, 100.0],
[100.0, 100.0, 100.0, 100.0]]

あなたのコードではなく、リストのマップオブジェクトを生成します >>> float_l = [map(float, nested_list) for nested_list in l] [[<map at 0x47be9b0>], [<map at 0x47be2e8>], [<map at 0x47be4a8>], [<map at 0x47beeb8>], [<map at 0x484b048>], [<map at 0x484b0b8>]] が、それは期待どおりに動作リストに追加呼び出しを追加: >>> float_l = [list(map(float, nested_list)) for nested_list in l]
pixelperfect

@pixelperfect(誤解された ..)が原因でpython3ジェネレータを理解できないように変更するためです。
javadba 2018年

3

解決すべき同様の問題があったので、この質問に出くわしました。Andrew Clarkとnarayanの答えを比較したいと思います。

2つの回答の主な違いは、内部リストを反復する方法です。1つは組み込みのmapを使用し、もう1つはリスト内包表記を使用しています。map関数は、ラムダを使用する必要がない場合、同等のリスト内包に比べてパフォーマンスがわずかに優れています。この質問の文脈ではmap、リストの理解よりもわずかに優れたパフォーマンスが得られるはずです。

パフォーマンスベンチマークを実行して、実際にそれが正しいかどうかを確認してみましょう。これらすべてのテストを実行するためにpythonバージョン3.5.0を使用しました。最初の一連のテストでは、リストごとの要素を10に保ち、リストの数を10〜100,000に変更します

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10]"
>>> 100000 loops, best of 3: 15.2 usec per loop   
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10]"
>>> 10000 loops, best of 3: 19.6 usec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100]"
>>> 100000 loops, best of 3: 15.2 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100]"
>>> 10000 loops, best of 3: 19.6 usec per loop 

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*1000]"
>>> 1000 loops, best of 3: 1.43 msec per loop   
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*1000]"
>>> 100 loops, best of 3: 1.91 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*10000]"
>>> 100 loops, best of 3: 13.6 msec per loop   
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*10000]"
>>> 10 loops, best of 3: 19.1 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 164 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,10))]*100000]"
>>> 10 loops, best of 3: 216 msec per loop

ここに画像の説明を入力してください

次の一連のテストでは、リストごとの要素数を100に増やしたいと思います。

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 110 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10]"
>>> 10000 loops, best of 3: 151 usec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.11 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100]"
>>> 1000 loops, best of 3: 1.5 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 11.2 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*1000]"
>>> 100 loops, best of 3: 16.7 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 134 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*10000]"
>>> 10 loops, best of 3: 171 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.32 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,100))]*100000]"
>>> 10 loops, best of 3: 1.7 sec per loop

ここに画像の説明を入力してください

勇敢な一歩を踏み出し、リストの要素数を1000に変更してみましょう

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 800 usec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10]"
>>> 1000 loops, best of 3: 1.16 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 8.26 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100]"
>>> 100 loops, best of 3: 11.7 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 83.8 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*1000]"
>>> 10 loops, best of 3: 118 msec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 868 msec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*10000]"
>>> 10 loops, best of 3: 1.23 sec per loop

>>> python -m timeit "[list(map(float,k)) for k in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 9.2 sec per loop
>>> python -m timeit "[[float(y) for y in x] for x in [list(range(0,1000))]*100000]"
>>> 10 loops, best of 3: 12.7 sec per loop

ここに画像の説明を入力してください

これらのテストからmap、この場合、リストの理解よりもパフォーマンス上の利点があると結論付けることができます。これは、intまたはにキャストしようとしている場合にも当てはまりますstr。リストあたりの要素が少ない少数のリストの場合、違いはごくわずかです。リストあたりの要素数が多い大きなリストの場合map、リスト内包表記の代わりに使用したいかもしれませんが、それは完全にアプリケーションのニーズに依存します。

しかし、私は個人的に、リストの内包表記がより読みやすく、慣用的であると感じていますmap。これは、Pythonの事実上の標準です。通常、人々はよりも、リストの内包表記を使用して(特別初級)より堪能で快適ですmap


2

はい、そのようなコードでそれを行うことができます:

l = [[float(y) for y in x] for x in l]

[float(y) for y in x for x in l]これは、2400の合計で100の束になります。–
Boy Pasmo

2

この問題はforループを使用しなくても解決できます。これには1行のコードで十分です。ネストされたマップをラムダ関数で使用することもここで機能します。

l = [['40', '20', '10', '30'], ['20', '20', '20', '20', '20', '30', '20'], ['30', '20', '30', '50', '10', '30', '20', '20', '20'], ['100', '100'], ['100', '100', '100', '100', '100'], ['100', '100', '100', '100']]

map(lambda x:map(lambda y:float(y),x),l)

また、出力リストは次のようになります。

[[40.0, 20.0, 10.0, 30.0], [20.0, 20.0, 20.0, 20.0, 20.0, 30.0, 20.0], [30.0, 20.0, 30.0, 50.0, 10.0, 30.0, 20.0, 20.0, 20.0], [100.0, 100.0], [100.0, 100.0, 100.0, 100.0, 100.0], [100.0, 100.0, 100.0, 100.0]]

1
ラムダスには、@ Andrew ClarkやHarry Binswangerのソリューション(よりバニラリストの理解)よりもパフォーマンス上の利点がありますか?ラムダは読みにくいように見えます。
StefanJCollier 2017年

0

私の意見では、これを行う最善の方法は、pythonのitertoolsパッケージを使用することです。

>>>import itertools
>>>l1 = [1,2,3]
>>>l2 = [10,20,30]
>>>[l*2 for l in itertools.chain(*[l1,l2])]
[2, 4, 6, 20, 40, 60]


-2
    deck = [] 
    for rank in ranks:
        for suit in suits:
            deck.append(('%s%s')%(rank, suit))

これはリスト内包表記を使用して実現できます。

[deck.append((rank,suit)) for suit in suits for rank in ranks ]

1
これは最上位の質問にまったく対処していないようです。回答として投稿されたものはすべて、投稿された質問に答えようとする試みでなければならないことに注意してください。
Baum mit Augen

このコードスニペットは問題を解決する可能性がありますが、説明を含めると、投稿の品質を向上させるのに役立ちます。あなたは将来の読者のための質問に答えていることを覚えておいてください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。また、コードと説明コメントを混同しないようにしてください。これにより、コードと説明の両方が読みにくくなります。
Filnor 2018年

リスト内包表記を使用してネストされたforループ
ADITYA KUMAR 2018年

1
わかりましたので、明らかに、これは質問に答える試みです。ただし、これはOPとはまったく異なるシナリオのようであり、ネストされたリストを入力として処理することもありません。また、提案が変更されても、提案はOPがすでに試みたものとほぼ同じです。また、質問が文字列を浮動小数点数に変換することに関するものである場合、カードに関する例がどのように役立つかはわかりません。
Baum mit Augen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.