リスト内包Pythonの2つのforループをフレーム化する方法


101

以下の2つのリストがあります

tags = [u'man', u'you', u'are', u'awesome']
entries = [[u'man', u'thats'],[ u'right',u'awesome']]

にあるentriesときにエントリを抽出したいtags

result = []

for tag in tags:
    for entry in entries:
        if tag in entry:
            result.extend(entry)

2つのループを単一行リスト内包表記としてどのように書くことができますか?


3
使用itertools.chainあなたが平らにリストをしたい場合:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
アシュビニーChaudharyさん

回答:


135

これはそれを行うはずです:

[entry for tag in tags for entry in entries if tag in entry]

156

これを覚える最良の方法は、リスト内包のforループの順序が、従来のループアプローチでの順序に基づいていることです。最も外側のループが最初に来て、次に内側のループが続きます。

したがって、同等のリスト内包表記は次のようになります。

[entry for tag in tags for entry in entries if tag in entry]

一般に、if-elseステートメントは最初のforループの前にあり、ステートメントだけの場合ifは最後に来ます。たとえば、空のリストを追加したい場合、tagがエントリにない場合は、次のようにします。

[entry if tag in entry else [] for tag in tags for entry in entries]

6

適切なLCは

[entry for tag in tags for entry in entries if tag in entry]

LCのループの順序は、ネストされたループのループの順序と似ています。ifステートメントは最後に移動し、条件式は最初に移動します。

[a if a else b for a in sequence]

デモを見る-

>>> tags = [u'man', u'you', u'are', u'awesome']
>>> entries = [[u'man', u'thats'],[ u'right',u'awesome']]
>>> [entry for tag in tags for entry in entries if tag in entry]
[[u'man', u'thats'], [u'right', u'awesome']]
>>> result = []
    for tag in tags:
        for entry in entries:
            if tag in entry:
                result.append(entry)


>>> result
[[u'man', u'thats'], [u'right', u'awesome']]

編集 -結果をフラット化する必要があるため、同様のリスト内包表記を使用して結果をフラット化できます。

>>> result = [entry for tag in tags for entry in entries if tag in entry]
>>> from itertools import chain
>>> list(chain.from_iterable(result))
[u'man', u'thats', u'right', u'awesome']

これを一緒に追加すると、あなたはただ行うことができます

>>> list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
[u'man', u'thats', u'right', u'awesome']

ここでは、リスト内包の代わりにジェネレータ式を使用します。(完全に79文字の制限にも一致します(list呼び出しなし))


2
tags = [u'man', u'you', u'are', u'awesome']
entries = [[u'man', u'thats'],[ u'right',u'awesome']]

result = []
[result.extend(entry) for tag in tags for entry in entries if tag in entry]

print(result)

出力:

['man', 'thats', 'right', 'awesome']

0

理解すると、ネストされたリストの反復は、対応するforforループと同じ順序に従う必要があります。

理解するために、NLPの簡単な例を取り上げます。各文が単語のリストである文のリストから、すべての単語のリストを作成するとします。

>>> list_of_sentences = [['The','cat','chases', 'the', 'mouse','.'],['The','dog','barks','.']]
>>> all_words = [word for sentence in list_of_sentences for word in sentence]
>>> all_words
['The', 'cat', 'chases', 'the', 'mouse', '.', 'The', 'dog', 'barks', '.']

繰り返される単語を削除するには、リスト[]の代わりにセット{}を使用できます

>>> all_unique_words = list({word for sentence in list_of_sentences for word in sentence}]
>>> all_unique_words
['.', 'dog', 'the', 'chase', 'barks', 'mouse', 'The', 'cat']

または適用する list(set(all_words))

>>> all_unique_words = list(set(all_words))
['.', 'dog', 'the', 'chases', 'barks', 'mouse', 'The', 'cat']

0
return=[entry for tag in tags for entry in entries if tag in entry for entry in entry]

6
こんにちは、Stack Overflowへようこそ!コードだけでなく説明も投稿してください。
エブリン

1
こんにちは!このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらく投票数が増えることになります。あなたが今尋ねている人だけでなく、将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。
ブライアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.