`elif` в условных выражениях понимания списка

129

Можем ли мы использовать elifпонимание списка?

Пример :

l = [1, 2, 3, 4, 5]

for values in l:
    if values==1:
        print 'yes'
    elif values==2:
        print 'no'
    else:
        print 'idle'

Можем ли мы включить elifв наше понимание списка аналогично приведенному выше коду?

Например, такой ответ:

['yes', 'no', 'idle', 'idle', 'idle']

До сих пор я использовал только ifи elseв понимании списка.

сам
источник

Ответы:

250

Условные выражения Python были разработаны именно для такого рода случаев использования:

>>> l = [1, 2, 3, 4, 5]
>>> ['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]
['yes', 'no', 'idle', 'idle', 'idle']

Надеюсь это поможет :-)

Раймонд Хеттингер
источник
5
В синтаксисе есть интересная история. За много лет до их появления «третичные выражения» были одним из пяти наиболее востребованных изменений в языке. Поскольку Гвидо ван Россум явно разработал его как язык, основанный на утверждениях, он долгое время твердо сопротивлялся (третичные выражения, и особенно их злоупотребление, являются источниками большой неясности в коде). Когда он наконец уступил, он объявил, что сознательно выбрал синтаксис, препятствующий чрезмерному использованию. Тем не менее, как обычно, он сделал элегантную дизайнерскую работу.
holdenweb
1
Тернарный, черт возьми (он написал, заметив свою дислексическую ошибку слишком поздно, чтобы редактировать).
holdenweb
2
Пока я голосую за этот ответ, я хочу упомянуть следующее: 1 пара if / else легко читается, 2 пары: становится труднее понять. Не говоря уже о 3 парах. Если для выражения требуется 3 или более пар, словарь или отдельная функция упростят чтение и понимание.
Хай Ву
1
Я хотел бы добавить не решение этой проблемы, а напоминание о чистом коде: поскольку это понимание списка имеет три условия, его, вероятно, можно было бы реорганизовать в более описательный метод. Моя точка зрения такова: martinfowler.com/bliki/FunctionLength.html :)
Альваро Кавальканти
Я наткнулся на случай, когда мне нужен elif, но только два значения. Используя этот пример, мне нужно было просто ['yes', 'no']сделать. Чтобы сделать это, вы можете сделать: ['yes' if v == 1 else 'no' for v in l if values in [1,2]]. В настоящее время я не могу придумать более чистого способа сделать это.
dTanMan
48
>>> d = {1: 'yes', 2: 'no'}
>>> [d.get(x, 'idle') for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
Игнасио Васкес-Абрамс
источник
4
Я думаю, что эту форму намного легче переварить, чем пытаться сделать действительно длинную и сложную логику if / else в списке comp
jdi
5
@jdi Хотя условные выражения могут не соответствовать вашему вкусу, они были специально разработаны для обработки цепочек if-elif-elif-else, как того требует OP. Они не трудно учиться и могут корректно обрабатывать ситуации, которые не как поддающийся словарь логики поиска: 'A' if grade>=90 else 'B' if grade>=80 else 'C' if grade>=70 else 'F'.
Раймонд Хеттингер,
1
Есть ли преимущество определения dвне понимания?
Chris_Rands
Причина, по которой мне больше нравится понимание списка, заключается в том, что он читается как английский. Даже непрограммист сможет понять, что он делает. С этим решением вы должны понимать метод dict.get ().
Тим Сков Якобсен
26

Можно, вроде того.

Обратите внимание, что когда вы используете синтаксис, например:

['yes' if v == 1 else 'no' for v in l]

Вы используете тернарную форму оператора if / else (если вы знакомы с такими языками, как C, это похоже на ?:конструкцию:) (v == 1 ? 'yes' : 'no').

Тернарная форма оператора if / else не имеет встроенного elif, но вы можете смоделировать его в условии else:

['yes' if v == 1 else 'no' if v == 2 else 'idle' for v in l]

Это как сказать:

for v in l:
    if v == 1 :
        print 'yes'
    else:
        if v == 2:
            print 'no'
        else:
            print 'idle'

Таким образом, нет прямой конструкции elif, о которой вы спрашивали, но ее можно смоделировать с помощью вложенных операторов if / else.

mathematical.coffee
источник
1
Код последнего абзаца очень полезен!
Devianceee
3

Может быть, ты хочешь этого:

l = [1, 2, 3, 4, 5] 

print ([['idle','no','yes'][2*(n==1)+(n==2)] for n in l])
Ратнеш Кушваха
источник
2

Вы можете использовать понимание списка, если собираетесь создать другой список из оригинала.

>>> l = [1, 2, 3, 4, 5]
>>> result_map = {1: 'yes', 2: 'no'}
>>> [result_map[x] if x in result_map else 'idle' for x in l]
['yes', 'no', 'idle', 'idle', 'idle']
San4ez
источник
2

Другой простой способ - использовать понимание условного списка следующим образом:

l=[1,2,3,4,5]
print [[["no","yes"][v==1],"idle"][v!=1 and v!=2] for v in l]

дает вам правильный ответ:

['да', 'нет', 'простаивает', 'простаивает', 'простаивает']

Стефан Грюнвальд
источник