Однозначне розуміння списку: варіанти "інше"


178

Йдеться більше про синтаксис розуміння списку python. У мене є розуміння списку, яке створює список непарних чисел даного діапазону:

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

Це робить фільтр - у мене є список джерел, з якого я видаляю парні числа ( if x % 2). Я хотів би тут використати щось на кшталт if-then-else. Наступний код не вдається:

>>> [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

Як використовувати його всередині списку?


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.


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 у вашому другому прикладі, це не тренажерний оператор, якщо інший (пропущений 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]
>>>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.