Один рядок if-умова-призначення


140

У мене є такий код

num1 = 10
someBoolValue = True

Мені потрібно встановити значення num1для 20якщо someBoolValueє True; і не робити нічого іншого. Отже, ось мій код для цього

num1 = 20 if someBoolValue else num1

Чи є якимось чином я міг би уникнути ...else num1частини, щоб зробити її більш чистою? Еквівалент

if someBoolValue:
    num1 = 20

Я спробував замінити його ...else passнаступним чином: num1=20 if someBoolValue else pass. Я отримав лише синтаксичну помилку. Я також не міг просто опустити цю ...else num1частину.


2
Просто змініть все на num1 = 20 if someBoolValue else 10. Тоді ви також збережете num1=10рядок?
Томас Ейл

Дякую. Але це не зовсім мій код. Я мав на увазі, що num1існує вже ...
bdhar

Відповіді:


195

Я не думаю, що це можливо в Python, оскільки те, що ви насправді намагаєтеся зробити, напевно, розширюється на щось подібне:

num1 = 20 if someBoolValue else num1

Якщо ви виключаєте else num1, ви отримаєте синтаксичну помилку, оскільки я цілком впевнений, що призначення повинно насправді щось повернути.

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

if someBoolValue: num1=20

Я не є великим шанувальником цієї num1 = someBoolValue and 20 or num1саме причини. Мені доводиться двічі подумати над тим, що робить ця лінія.

Найкращий спосіб реально досягти того, що ви хочете зробити, - це оригінальна версія:

if someBoolValue:
    num1 = 20

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

Крім того, в якості побічної примітки num1 = 20 if someBoolValueдіє дійсний код Ruby, оскільки Ruby працює трохи інакше.


8
Згідно з PEP-308 ( docs.python.org/2.5/whatsnew/pep-308.html ) умовне вираження може бути зрозумілішим, якщо його ввести у батьків, як у num1 = (20 if someBoolValue else num1).
haridsv

46

Використовуй це:

num1 = 20 if someBoolValue else num1

3
це те, що я використовував .. і шукаю альтернативу .. дякую все одно !!
bdhar

Як викликати цей блок? Я маю на увазі, як це звуть?
fuat

1
це потрійний оператор
Кріс Мейс

Не слід застосовувати цей підхід, якщо переглядати великі набори даних, оскільки він вводить непотрібне завдання у випадку, якщо ми опинимося в операторі else.
dapc

21

В одному рядку:

if someBoolValue: num1 = 20

Але не робіть цього. Такого стилю зазвичай не передбачається. Люди віддають перевагу більш довгій формі для ясності та послідовності.

if someBoolValue:
    num1 = 20

(Так само слід уникати верблюжих шапок. Тому скоріше використовуйте some_bool_value.)

Зауважте, що рядкове вираження some_value if predicate без elseчастини не існує, оскільки не було б значення повернення, якби присудок був помилковим. Однак вирази повинні мати чітко визначене повернене значення у всіх випадках. Це відрізняється від використання, як, наприклад, у Ruby або Perl.


2
Тому що це важко читати, і ви, ймовірно, в результаті заплутаєтесь у власному коді, і це ніколи не є хорошою ідеєю.
Мороз

@bdhar, чому ти хочеш поставити його в одну лінію? Він не запуститься швидше, іншим людям просто буде важче читати
Джон Ла Рой

1
@gnibbler, насправді немає причини. я шукав більш коротку форму з кращою читабельністю ..
bdhar

17

ви можете скористатися одним із наступних:

(falseVal, trueVal)[TEST]

TEST and trueVal or falseVal

1
Приємне умовне завдання для одного лайнера
minhas23

Як називається ця "структура"? Я ніколи не бачив цього за ~ 6 місяців навчання Python.
Гімуте

1
Принаймні, це не завдання, якщо ви не поставите їх перед ними, а по-друге, вони не працюватимуть так, як описано тут. Перший створює кортеж, потім вибирає один з його елементів за індексом. Він буде працювати лише для тестів, які повертають ціле число між -1 і 1, або True/ False, оскільки boolє підкласом int. У всіх випадках, коли тест повертає те, що було б просто оцінено істинним, воно не вдається за винятком. Другий працює лише до тих пір, trueValпоки не оцінить помилковість, що призведе до falseValприсвоєння бджоли, навіть якщо тест був істинним.
Бахсау

це дуже коротко, але також дуже складно, щоб безпечно використовувати його як "рекомендований зразок", див. вище коментар Бахсау ... (так я його спростував)
tverrbjelke

6

Ні, я гадаю, ви сподівалися, що щось подібне num1 = 20 if someBoolValueспрацює, але це не так. Я думаю, що найкраще - із ifзаявою, як ви її написали:

if someBoolValue:
    num1 = 20

5
num1 = 10 + 10*(someBoolValue is True)

Це моя нова остаточна відповідь. Попередня відповідь була такою, і вона була надмірна для заявленої проблеми. Getting_too_clever == not Good. Ось попередня відповідь ... все-таки добре, якщо ви хочете додати одне для Truecond, а інше для False:

num1 = 10 + (0,10)[someBoolValue is True]

Ви згадали, num1що вже мали б значення, яке слід залишити в спокої. Я припустив, num1 = 10що це перша заява повідомлення, тому операція, яку потрібно отримати, - 20це додати 10.

num1 = 10
someBoolValue = True

num1 = 10 + (0,10)[someBoolValue is True]

print(f'num1 = {num1}\nsomeBoolValue = {someBoolValue}')

дав цей вихід

num1 = 20
someBoolValue = True

Тепер я думаю, що я мав би відповісти "num1 = 10 + 10 * (someBoolValue == True)" Проблема, визначена як умова "False", як не-оп. Якщо для вибору потрібно додати інше значення для 'False', то попередня відповідь - це більше. Чи редагувати свою публікацію чи робити це в коментарях?
MikeyB


2

Якщо ви хочете скористатися методом, якщо якийсь булевий істинний, ви можете поставити else Noneзаяву про припинення тринаціональної роботи.

>>> a=1
>>> print(a) if a==1 else None
1
>>> print(a) if a==2 else None
>>> a=2
>>> print(a) if a==2 else None
2
>>> print(a) if a==1 else None
>>>

1

Якщо один код рядка точно відбудеться для вас, Python 3.8 вводить вирази призначення, ласкаво відомі як «оператор моржів».

:=

someBoolValue and (num := 20)

20Буде призначено , numякщо перше логічне вираз True. Призначення повинно бути в дужках, інакше ви отримаєте синтаксичну помилку.

num = 10
someBoolValue = True

someBoolValue and (num := 20)
print(num) # 20

num = 10
someBoolValue = False

someBoolValue and (num := 20)
print(num) # 10

0

Для майбутнього мандрівника в часі від Google, ось новий спосіб (доступний від python 3.8 і далі):

b = 1
if a := b:
    # this section is only reached if b is not 0 or false.
    # Also, a is set to b
    print(a, b)

-1

Ви, безумовно, можете використовувати num1 = (20, якщо деякіBoolValue ще число1), якщо ви хочете.


Дублікат відповідей (-ів) вище?
Адам Сміт

-1

Ось що я можу запропонувати. Використовуйте іншу змінну, щоб отримати пункт if і призначити її num1.

Код:

num2 =20 if someBoolValue else num1
num1=num2


-1

Ви можете це зробити так.

try:
    a = [i for i in [20] if False][0]
except IndexError:
    print("Do what ever you want here")

Ви можете вирішити свою проблему таким чином, але, використовуючи "спробувати / крім блоку", це не найкраща практика для python.

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