リスト内包表記のif / else


回答:


1460

あなたはそれを完全に行うことができます。それは単なる注文の問題です:

[unicode(x.strip()) if x is not None else '' for x in row]

一般に、

[f(x) if condition else g(x) for x in sequence]

そして、if条件のみを含むリスト内包については、

[f(x) for x in sequence if condition]

これは実際には別の言語構造、条件式を使用していることに注意してください。条件式自体は内包構文の一部ではありませんが、ifアフターfor…inはリスト内包の一部であり、ソース反復可能要素から要素をフィルターするために使用されます


条件式は、何らかの条件に基づいて2つの式の値から選択するあらゆる種類の状況で使用できます。これは、他の言語にある三項演算子?:と同じです。例えば:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

141
ここでのif / elseは「三項演算子」構文であり、リスト内包構文ではないことに注意してください。
Adam Vandenberg

8
そのため、三項演算子を角かっこで囲みます。これにより、内包ではなく、単なる正規表現であることが明確になります。
Jochen Ritzel、2010年

17
したがって、コツは、「リストの圧縮で、もし前にそれ以外の部分も追加しなければならない場合、私は書く」です。私はあればあるためl = [ 2, 3, 4, 5]、その後[x if x % 2 == 0 for x in l]、私は一方でエラー与える[x if x % 2 == 0 else 200 for x in l]作品。はい私はそれをフィルタリングすることを知っています私は書くべき[ x for x in l if x % 2 == 0]です。ご迷惑をおかけして申し訳ありません。ご回答有難うございます。
Grijesh Chauhan 2013

5
Pythonのドキュメントは、三項演算子を言及します。elseが必要であるか、機能しないことに注意してください。
naught101

4
@Drewdinリストの内包表記は、反復中の分割をサポートしていません。その場合は、通常のループを使用する必要があります。
2015年

44

一方通行:

def change(f):
    if f is None:
        return unicode(f.strip())
    else:
        return ''

row = [change(x) for x in row]

それでもあなたは持っています:

row = map(change, row)

または、ラムダをインラインで使用できます。


13
これは、ifelseブロックまたはsステートメントブロック内の式またはコードから発生する可能性のある例外を処理する必要がある場合に使用する(おそらく唯一の)優れた手法でもあります。受け入れられた答えは、単純な場合に適しています。
martineau

37

次に、別の例を示します。

>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!

関数によって生成された他のすべての値に対してfor およびfor とif i評価されるという事実を利用します。したがって、リスト内包は次のように評価されます。False0Truerange()

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']

37

特定の問題は以前の回答ですでに解決されているので、リスト内包表記の中で条件文を使用するという一般的な考え方を取り上げます。

リスト内包表記の中に条件文をどのように記述することができるかを示す例を次に示します。

X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a']     # Original list

# Extract non-strings from X to new list
X_non_str = [el for el in X if not isinstance(el, str)]  # When using only 'if', put 'for' in the beginning

# Change all strings in X to 'b', preserve everything else as is
X_str_changed = ['b' if isinstance(el, str) else el for el in X]  # When using 'if' and 'else', put 'for' in the end

の最初のリスト内包表記でX_non_strは、順序は次のとおりです。

表現 のための 項目 反復可能 であれば 条件

の最後のリスト内包表記でX_str_changedは、順序は次のとおりです。

式1 であれば 条件 expression2の ための 項目 反復可能

ife1if ifの前にあり、expression2elseの後にある必要があることを覚えておくのはいつも困難です。私の頭は両方とも前か後のどちらかになりたいです。

「雨が降ったら家にいたい、さもなく外に出たい」など、普通の言葉に似ているのでそういう風にデザインされていると思います

プレーンな英語では、上記の2種類のリスト内包表記は次のように表現できます。

のみif

extract_apple のための リンゴ box_of_apples 場合 apple_is_ripe

if/else

mark_apple if apple_is_ripe else leave_it_unmarked for apple in box_of_apples


7

他のソリューションは、単一のif/ else構成に最適です。ただし、リスト内包表記内の三項ステートメントは、間違いなく読むのが困難です。

関数を使用すると読みやすさが向上しますが、そのようなソリューションは、マッピングが入力であるワークフローで拡張または適応することが困難です。辞書はこれらの懸念を軽減することができます:

row = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]

d = {None: '', 'filler': 'manipulated'}

res = [d.get(x, x) for x in row]

print(res)

['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']

1

リストの理解がどのように行われるかに関係しています。

次の点に注意してください。

[ expression for item in list if conditional ]

以下と同等です。

for item in list:
    if conditional:
        expression

expression形式が少し異なる場合(主語と動詞の順序を文で切り替えることを検討してください)。

したがって、あなたのコード[x+1 for x in l if x >= 45]はこれを行います:

for x in l:
    if x >= 45:
        x+1

ただし、このコード[x+1 if x >= 45 else x+5 for x in l]はこれを実行します(を再配置した後expression):

for x in l:
    if x>=45: x+1
    else: x+5

0

3項のif / then / elseは必要ありません。私の意見では、あなたの質問はこの答えを必要としています:

row = [unicode((x or '').strip()) for x in row]

0

イテラブル内のアイテムからリストを作成する

質問に特定の答えを出すのではなく、まず可能な形式をすべて一般化するのが最善のようです。そうでなければ、読者は答えがどのように決定されたかを知りません。最後のelse句を最後のフォームで使用できるかどうかを判断しようと頭痛がする前に考えたいくつかの一般化されたフォームを次に示します。

[expression1(item)                                        for item in iterable]

[expression1(item) if conditional1                        for item in iterable]

[expression1(item) if conditional1 else expression2(item) for item in iterable]

[expression1(item) if conditional1 else expression2(item) for item in iterable if conditional2]

の値はitem、条件節で使用する必要はありません。A conditional3は、出力リストに値を追加するかどうかを切り替えるスイッチとして使用できます。

たとえば、空の文字列または空白文字列を元の文字列リストから削除する新しいリストを作成するには、次のようにします。

newlist = [s for s in firstlist if s.strip()]

1
2つ目は、ティムコメントで答えたときにエラーを出します。Pythonのドキュメントの条件ステートメントも参照してください。私にはまったく判読できません。概要:this if condition else thatまたは正規表現のみが許可されます。value = this if conditionできません(これはで達成できますvalue = this if condition else None
アンデリウム

0

条件ロジックを組み合わせて理解することができます。

 ps = PorterStemmer()
 stop_words_english = stopwords.words('english')
 best = sorted(word_scores.items(), key=lambda x: x[1], reverse=True)[:10000]
 bestwords = set([w for w, s in best])


 def best_word_feats(words):
   return dict([(word, True) for word in words if word in bestwords])

 # with stemmer
 def best_word_feats_stem(words):
   return dict([(ps.stem(word), True) for word in words if word in bestwords])

 # with stemmer and not stopwords
 def best_word_feats_stem_stop(words):
   return dict([(ps.stem(word), True) for word in words if word in bestwords and word not in stop_words_english])

-2
# coding=utf-8

def my_function_get_list():
    my_list = [0, 1, 2, 3, 4, 5]

    # You may use map() to convert each item in the list to a string, 
    # and then join them to print my_list

    print("Affichage de my_list [{0}]".format(', '.join(map(str, my_list))))

    return my_list


my_result_list = [
   (
       number_in_my_list + 4,  # Condition is False : append number_in_my_list + 4 in my_result_list
       number_in_my_list * 2  # Condition is True : append number_in_my_list * 2 in my_result_list
   )

   [number_in_my_list % 2 == 0]  # [Condition] If the number in my list is even

   for number_in_my_list in my_function_get_list()  # For each number in my list
]

print("Affichage de my_result_list [{0}]".format(', '.join(map(str, my_result_list))))

(venv)$ python list_comp.py
Affichage de my_list [0、1、2、3、4、5]
Affichage de my_result_list [0、5、4、7、8、9]

だから、あなたのために: row = [('', unicode(x.strip()))[x is not None] for x in row]


何をしてない「Affichageデ...」意味ですか?フランス人?
Peter Mortensen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.