Вопрос-Ответ

if/else in a list comprehension

понимание if / else в списке

Как мне преобразовать следующий forцикл, содержащий if/else, в понимание списка?

results = []
for x in xs:
results.append(f(x) if x is not None else '')

Это должно выдавать '' if x is None, и в противном случае f(x).
Я пробовал:

[f(x) for x in xs if x is not None else '']

но это дает SyntaxError. Каков правильный синтаксис?


Смотрите Есть ли в Python троичный условный оператор? для получения информации о ... if ... else ....

См. Понимание списка с условием для пропуска значений на основе условия: [... for x in xs if x cond].

См. `elif` в условных обозначениях понимания списка для elif.

Переведено автоматически
Ответ 1

Вы вполне можете это сделать. Это просто проблема с порядком:

[f(x) if x is not None else '' for x in xs]

В общих чертах,

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

И, только для понимания списка с if условиями,

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

Обратите внимание, что на самом деле здесь используется другая языковая конструкция, условное выражение, которое само по себе не является частью синтаксиса понимания, в то время как if после for…in является частью понимания списка и используется для фильтрации элементов из исходного итерируемого.


Условные выражения можно использовать во всех видах ситуаций, когда вы хотите выбрать одно из двух значений выражения на основе некоторого условия. Это делает то же самое, что и троичный оператор ?:, который существует в других языках. Например:

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

Давайте воспользуемся этим вопросом для обзора некоторых концепций. Я думаю, что сначала полезно ознакомиться с основными принципами, чтобы вы могли экстраполировать их на различные случаи.

Другие ответы дают конкретный ответ на ваш вопрос. Сначала я приведу некоторый общий контекст, а затем отвечу на вопрос.

Основы

if/else инструкции в понимании списка включают две вещи:


  • Понимание списка

  • Условные выражения (троичные операторы)

1. Понимание списка

Они предоставляют краткий способ создания списков.

Его структура состоит из: "скобки, содержащие выражение, за которым следует предложение for, затем ноль или более предложений for или if".

Пример 1

Здесь у нас нет условия. Каждый элемент из итерируемого добавляется в new_list.

new_list = [expression for item in iterable]
new_list = [x for x in range(1, 10)]
> [1, 2, 3, 4, 5, 6, 7, 8, 9]

Пример 2

Здесь у нас есть одно условие.

Пример 1

Условие: в будут добавлены только четныеnew_list числа.

new_list = [expression for item in iterable if condition == True]
new_list = [x for x in range(1, 10) if x % 2 == 0]
> [2, 4, 6, 8]

Пример 2

Условие: в будут добавлены только четныеnew_list числа, кратные 3.

new_list = [expression for item in iterable if condition == True]
new_list = [x for x in range(1, 10) if x % 2 == 0 if x % 3 == 0]
> [6]

Но почему у нас есть одно условие, если мы используем два if в new_list?

Предыдущее выражение может быть записано как:

new_list = [x for x in range(1, 10) if x % 2 and x % 3 == 0]
> [6]

Мы используем только один оператор if.

Это похоже на выполнение:

new_list = []
for x in range(1, 10):
if x % 2 == 0 and x % 3 == 0:
new_list.append(x)
> [6]

Пример 3

Просто ради аргументации вы также можете использовать or.

Условие: в будут добавлены четныеnew_list числа или числа, кратные 3.

new_list = [x for x in range(1, 10) if x % 2 == 0 or x % 3 == 0]
> [2, 3, 4, 6, 8, 9]

Пример 3

Более одного условия:

Здесь нам понадобится помощь условных выражений (троичных операторов).

2.Условные выражения

Что такое условные выражения? О чем говорит название: выражение Python, имеющее некоторое условие.

<Exp1> if condition else <Exp2>

Сначала вычисляется condition. Если condition есть True, то <Exp1> вычисляется и возвращается. Если condition есть False, то <Exp2> вычисляется и возвращается.

Условное выражение с более чем одним условием:

<Exp1> if condition else <Exp2> if condition else <Exp3>...    

Пример из реального Python:

age = 12
s = 'minor' if age < 21 else 'adult'
> minor

Значение s обусловлено age значением.

3.Понимание списка с помощью условных обозначений

Мы объединяем понимание списка и условные выражения следующим образом.

new_list = [<Conditional Expression> for <item> in <iterable>]

new_list = [<Exp1> if condition else <Exp2> if condition else <Exp3> for <item> in <iterable>]

Условие: четные числа будут добавлены как 'even', число три будет добавлено как 'number three', а остальные будут добавлены как 'odd'.

new_list = ['even' if x % 2 == 0 else 'number three' if x == 3 else 'odd' 
for x in range(1, 10)]
> ['odd', 'even', 'number three', 'even', 'odd', 'even', 'odd', 'even', 'odd']

Ответ на вопрос

[f(x) for x in xs if x is not None else '']

Здесь у нас проблема со структурой списка: for x in xs должно быть в конце выражения.

Правильный способ:

[f(x) if x is not None else '' for x in xs]

Дальнейшее чтение:

Есть ли в Python троичный условный оператор?

Ответ 3

Конкретная проблема уже была решена в предыдущих ответах, поэтому я рассмотрю общую идею использования условных выражений внутри понимания списка.

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

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 порядок такой:


выражение для элемента в повторяемом условии if


и в последнем понимании списка для X_str_changed порядок такой:


выражение1 if условие else выражение2 для элемента в итерируемом


Мне всегда трудно запомнить, что expression1 должно быть перед if, а expression2 должно быть после else. Моя голова хочет, чтобы оба были либо до, либо после.

Я думаю, это разработано так, потому что напоминает обычный язык, например "Я хочу остаться внутри, если пойдет дождь, иначе я хочу выйти наружу"

Простым английским упомянутые выше два типа понимания списка могут быть сформулированы как:

Только с if:


извлеки_apple для apple в apple_box if apple_is_ripe


и с if/else


отметьте_apple если apple_is_ripe else оставьте_it_unmarked для apple в apple_box


Ответ 4

Один из способов:

def change(x):
if x is None:
return f(x)
else:
return ''

result = [change(x) for x in xs]

Хотя тогда у вас есть:

result = map(change, xs)

Или вы можете использовать встроенную лямбду.

2023-09-29 15:57 python list