Тернарний оператор Python без іншого


85

Чи можна це зробити в одному рядку в Python?

if <condition>:
    myList.append('myString')

Я спробував тернарний оператор:

myList.append('myString' if <condition>)

але моїй IDE ( MyEclipse ) це не сподобалось, без else.


1
Ви маєте на увазі як трійковий оператор, який не має трьох частин? Хіба це не суперечність у термінах?
user207421

Відповіді:


119

Так, ви можете зробити це:

<condition> and myList.append('myString')

Якщо <condition>значення хибне, тоді спрацює коротке замикання, а права частина не буде оцінена. Якщо <condition>це істина, тоді буде оцінено праву сторону та додано елемент.

Я просто зазначу, що робити вищезазначене досить непітонічно, і, мабуть, найкраще було б написати це, незалежно від того:

if <condition>: myList.append('myString')

Демонстрація:

>>> myList = []
>>> False and myList.append('myString')
False
>>> myList
[]
>>> True and myList.append('myString')
>>> myList
['myString']

10
Хоча ця відповідь є технічно правильною, це не є хорошою практикою програмування. Оскільки Python прагне бути мовою, яка легко читається, цей код буде вважатися непітонічним.
Mr. Lance E Sloan

10
@LS: Я згоден, саме тому я сказав, що, мабуть, було б найкраще просто використати вислів if. Але я трохи змінив відповідь, щоб зробити це зрозумілішим.
Клавдіу

2
fyi другий приклад провалить перевірки pep8: E701 multiple statements on one lineтак само і непітонічні ...;)
Cas

1
@hard_working_ant "Правильний" спосіб був би x = object.get('attribute')в такому випадку
wihlke

1
@wihlke: так і подальше додавання x = object.get ('атрибут', None) за замовчуванням до None
hard_working_ant

45

Причина, по якій мова не дозволяє використовувати синтаксис

variable = "something" if a_condition

без else- це те, у випадку де a_condition == False, variableраптом невідомо. Можливо, це могло б за замовчуванням None, але Python вимагає, щоб усі призначення змінних насправді мали результатом явні призначення. Це також стосується таких випадків, як виклик функції, оскільки значення, передане функції, обчислюється так само, як і RHS оператора присвоєння.

Подібним чином усі returns повинні фактично повернутися, навіть якщо вони є умовними returns. Наприклад:

return variable if a_condition

не дозволяється, але

return variable if a_condition else None

дозволено, оскільки другий приклад гарантовано явно щось повертає.


1
Іронічно, як Python не дозволяє нам використовувати це, щоб така змінна ніколи ще не variable=Noneбула абсолютно законною. : D
Гай

1
Але я хотів використовувати його так: continue if i == 0у циклі for.
karantan

2
Вам дозволено це робитиelse pass?
OldBunny2800

5
else passне працює, оскільки тернарний вираз повинен повертати значення, якому можна передати return. passне є дійсним returnзначенням.
Еммет Батлер

4
Я не згоден з тим, що ця мотивація є справжньою причиною, враховуючи це if a_condition: variable = "something"та if a_condition: return variableє законною. Отже, це, по суті, довільний синтаксичний вибір пітона.
oulenz,

13
if <condition>: myList.append('myString')

В іншому випадку ні. Навіщо потрібно ставити його в один рядок?

Зверніть увагу, що "потрійний оператор" - це оператор . Як і будь-який оператор, він повинен щось повертати , так як же ви можете мати тернарний оператор без elseпропозиції? Що він повинен повернути, якщо умова не відповідає дійсності?


10

Ви в основному просите do_thing() if <condition> else passконструкт (який кине SyntaxError, якщо буде запущений). Як я виявив під час досліджень для (дещо) подібного запитання, do_thing() if condition else None це найближче, наскільки це можливо (що є лише іншим способом зробити <condition> and do_thing()). Отже, щоб підсумувати цю ідею та інші відповіді, ось ваші варіанти:

  • if <condition>: myList.append('myString') - здається, найменш "хакі" (і, отже, кращий) спосіб
  • <condition> and myList.append('myString')
  • myList.append('myString') if <condition> else None

Найменш вдалий спосіб не працює. Принаймні не на REPL - виникає синтаксична помилка. Здається, це спричинено попереднім кодом у тому самому рядку. Натомість це потрібно виконати на власному рядку. Але навіть тоді потрібно ввести користувач, щоб пропустити еліпсис.
Unknow0059


0

Ви можете зробити щось подібне:

myList.append('myString') if <condition> else False

або

myList.append('myString') if <condition> else 0

Помилкові та 0 не додаються до списку. Рядок просто повинен щось повернути, якщо умова не виконана. Ви можете замінити 0 або False на None або порожній рядок або що завгодно, і це не вплине на список.
Захарі Кіодіні,

Я думаю, що моя думка тоді була щодо розуміння списку. Мій коментар видалено, голос проти - не я. Я гадаю, це було б зробити більш чистим способом. myList.append('myString') if True else _Але якщо ви нічим не займаєтесь, не має значення. Мене турбує ця людина, яка намагається зрозуміти список зі схожою логікою.
Дейв Лю

0

я б просто зробив це, якщо хочу додати необов’язкові елементи до списку на основі умови.

nums = [
        1,
        2,
        3 if <condition> else None,
        4,
       ]
nums = [i for i in nums if i is not None]

це просто замінює значення на None, якщо умова не виконується, а потім, воно просто перевизначає список без значень None. таким чином вони зберігають свій індекс, якщо умова дотримана

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.