Понимание списка в одну строку: варианты if-else

178

Это больше о синтаксисе понимания списка Python. У меня есть понимание списка, которое производит список нечетных чисел данного диапазона:

[x for x in range(1, 10) if x % 2]

Это делает фильтр - у меня есть список источников, где я удаляю четные числа ( if x % 2). Я хотел бы использовать что-то вроде «если-то-еще» здесь. Следующий код не работает:

>>> [x for x in range(1, 10) if x % 2 else x * 100]
  File "<stdin>", line 1
    [x for x in range(1, 10) if x % 2 else x * 100]
                                         ^
SyntaxError: invalid syntax

Есть выражение на python, как if-else:

1 if 0 is 0 else 3

Как использовать это в понимании списка?

ducin
источник
1
Что бы это ни стоило, у вас есть «понимание списка», а не генератор. Окончательный синтаксис тот же, за исключением того, что генераторы используют ()вместо [].
mgilson
2
Мне потребовалось некоторое время, чтобы понять, почему я if x % 2 удаляю четные числа (вместо того, чтобы хранить их) - это потому, что когда xполучается даже x % 2выражение 0, которое, в свою очередь, оценивает False, в то время как любое, intкроме, 0оценивает True.

Ответы:

328

x if y else zэто синтаксис выражения, которое вы возвращаете для каждого элемента. Таким образом вам нужно:

[ x if x%2 else x*100 for x in range(1, 10) ]

Путаница возникает из-за того, что вы используете фильтр в первом примере, а не во втором. Во втором примере вы только отображаете каждое значение в другое, используя выражение троичного оператора.

С фильтром вам нужно:

[ EXP for x in seq if COND ]

Без фильтра вам нужно:

[ EXP for x in seq ]

и во втором примере выражение является «сложным» и включает в себя if-else.

shx2
источник
2
У меня есть один вопрос ... [x for x in range(1, 10) if x % 2]правильный синтаксис. [x if x % 2 for x in range(1, 10)]- это не так, но [x if x%2 else x*100 for x in range(1, 10)]опять-таки правильный синтаксис. Как придешь?
Ducin
@tkoomzaaskz во втором примере, это не троичный оператор if-else (пропущенный else), ни фильтр (так как он EXPвходит в состав списка)
shx2
3
@tkoomzaaskz Чтобы уточнить, обратите внимание, что ifв конце можно добавить секунду : [x if x%2 else x*100 for x in range(1, 10) if not x%3]первый ifявляется частью троичного оператора, второй if- частью синтаксиса понимания списка. Целое x if x%2 else x*100«на одном уровне», как простое 2*x, это выражение для оценки в левой части for, когда фильтрация if not x%3уже произошла.
zx81
Здравствуйте, будет ли однострочный оператор более производительным, чем сделать его в две строки, как for i in x:и затем в цикле for if i == y:?
Alexis.Rolland
12

Вы можете сделать это с помощью понимания списка:

A=[[x*100, x][x % 2 != 0] for x in range(1,11)]
print A
Стефан Грюнвальд
источник
1
Очень хорошо. Логический фрагмент Спасибо, вы только что дали мне более легкое для чтения решение.
Вы также можете назначить двойное назначение следующим образом: A, B = [10,11] [a == 19], [1,14] [a == 20]
Стефан Грюнвальд
10

Просто другое решение, надеюсь, кому-то это понравится:

Использование: [False, True] [Expression]

>>> map(lambda x: [x*100, x][x % 2 != 0], range(1,10))
[1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>
Джеймс Сапам
источник
3

Я смог сделать это

>>> [x if x % 2 != 0 else x * 100 for x in range(1,10)]
    [1, 200, 3, 400, 5, 600, 7, 800, 9]
>>>
anudeep
источник