条件に基づいてリストの理解を破るにはどうすればよいですか?たとえば、番号412
見つかった?
コード:
numbers = [951, 402, 984, 651, 360, 69, 408, 319, 601, 485, 980, 507, 725, 547, 544,
615, 83, 165, 141, 501, 263, 617, 865, 575, 219, 390, 984, 592, 236, 105, 942, 941,
386, 462, 47, 418, 907, 344, 236, 375, 823, 566, 597, 978, 328, 615, 953, 345, 399,
162, 758, 219, 918, 237, 412, 566, 826, 248, 866, 950, 626, 949, 687, 217, 815, 67,
104, 58, 512, 24, 892, 894, 767, 553, 81, 379, 843, 831, 445, 742, 717, 958, 609, 842,
451, 688, 753, 854, 685, 93, 857, 440, 380, 126, 721, 328, 753, 470, 743, 527]
even = [n for n in numbers if 0 == n % 2]
機能的には、これが何をすべきかを推測することができます:
even = [n for n in numbers if 0 == n % 2 and break if n == 412]
I 本当に好む:
import
ステートメントなどを使用しないでください)even = [n for n in numbers[:None if 412 not in numbers else numbers.index(412)] if not n % 2]
上記のF.J.のコードを取得し、412がリストにあるかどうかを確認するために3項を追加しました。それでも「1つのライナー」であり、412がリストにない場合でも機能します。
関数を使用してStopIteration
とlist
を上げてキャッチします。
>>> def end_of_loop():
... raise StopIteration
...
>>> even = list(end_of_loop() if n == 412 else n for n in numbers if 0 == n % 2)
>>> print(even)
[402, 984, 360, 408, 980, 544, 390, 984, 592, 236, 942, 386, 462, 418, 344, 236, 566, 978, 328, 162, 758, 918]
不平を言う人にとっては、それはワンライナーではありません:
even = list(next(iter(())) if n == 412 else n for n in numbers if 0 == n % 2)
不満を言う人にとっては、それはハック的であり、本番コードで使用すべきではありません。まあ、あなたは正しいです。 間違いなく
ジェネレーター式はitertools.takewhile()
と一緒に使用できます。
even_numbers = (n for n in numbers if not n % 2)
list(itertools.takewhile(lambda x: x != 412, even_numbers))
編集:import
sを使用しないという要件に気付きました。とにかく、私はこの答えをここに残します。
412が間違いなくリストに含まれる場合は、これを使用できます。
_even = [n for n in numbers[:numbers.index(412)] if not n % 2]
_
結果に412を含めたい場合は、スライスにnumbers[:numbers.index(412)+1]
を使用します。
スライスのために、これはitertoolsやforループソリューションよりも効率が悪い(少なくともメモリに関して)ことに注意してください。
リスト表示(リスト内包表記を含む)の構文は次のとおりです。 http://docs.python.org/reference/expressions.html#list-displays
ご覧のとおり、特別なwhile
またはuntil
構文はありません。最も近いものは次のとおりです。
even_numbers = (n for n in numbers if 0 == n % 2)
list(itertools.takewhile(lambda x: x != 412, even_numbers))
(私がこれを入力している間に投稿されたSven Marnachの回答から取られたコード)。
end
条件の助けを借りて、_breaking in list comprehension
_を解くための別の卑劣な1行のソリューション。
numbers.index(412)
を使用せずに、おそらく少し高速ですか?
_even = [n for end in [[]] for n in numbers
if (False if end or n != 412 else end.append(42))
or not end and not n % 2]
_
注:これは悪い考えです。 ただの楽しみのために:)
@WolframHが言ったように:
不満を言う人にとっては、それはハック的であり、本番コードで使用すべきではありません。まあ、あなたは正しいです。 間違いなく