Одна строка, если условие-присваивание

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часть.

bdhar
источник
2
Просто измени все это на num1 = 20 if someBoolValue else 10. Тогда вы также сохраните num1=10строку?
Томас Але
Спасибо. Но это не совсем мой код. Я имел в виду, что num1уже существует ...
Bdhar

Ответы:

196

Я не думаю, что это возможно в 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 ) условное выражение можно сделать более понятным, если поместить в paren, как в num1 = (20 if someBoolValue else num1).
haridsv
46

Использовать это:

num1 = 20 if someBoolValue else num1
gigimon
источник
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.

Debilski
источник
2
Потому что его трудно читать, и вы, вероятно, в конечном итоге запутаетесь в своем собственном коде, и это никогда не будет хорошей идеей.
Мороз
@bdhar, почему ты хочешь поместить это в одну строку? Он не будет работать быстрее, другим будет труднее читать
Джон Ла Руи,
1
@gnibbler, нет причин, на самом деле. я искал более короткую форму с лучшей читабельностью ..
Bdhar
17

Вы можете использовать один из следующих:

(falseVal, trueVal)[TEST]

TEST and trueVal or falseVal
kerwal
источник
1
Хорошее условное назначение одного лайнера
minhas23
Как называется эта «структура»? Я никогда не видел этого за 6 месяцев изучения Python.
Гимут
1
По крайней мере, это не задания, если вы не поставите одно перед ними, а во-вторых, они не будут работать так, как описано здесь. Первый создает кортеж, затем выбирает один из его элементов по индексу. Он будет работать только для тестов, которые возвращают целое число от -1 до 1 или True/ False, так boolкак является подклассом int. Во всех случаях, когда тест возвращает что-то, что просто оценило бы значение true, оно завершается с исключением. Второй работает только до тех пор, пока trueValсам не оценивает false, что приведет к тому, что его falseValназначат, даже если тест был верным.
Бахсау
это красиво короткий, но очень сложно безопасно использовать в качестве «рекомендуемого шаблона», см выше комментарий от Bachsau ... (так что я downvoted его)
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
MikeyB
источник
Теперь я думаю, что я должен был ответить 'num1 = 10 + 10 * (someBoolValue == True)' Проблема, определенная как условие «Ложь», как неактивная в принципе. Если нужно было добавить другое значение для «Ложь», тогда предыдущий ответ лучше подходит. Я редактирую свой пост или делаю это в комментариях?
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
>>>
soultech67
источник
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, если someBoolValue еще num1), если хотите.

Яонан Цянь
источник
Дубликат ответа (ов) выше?
Адам Смит
-1

Вот что я могу предложить. Используйте другую переменную для получения предложения if и присвойте его num1.

Код:

num2 =20 if someBoolValue else num1
num1=num2
J Raj
источник
-1

По-другому num1 = (20*boolVar)+(num1*(not boolVar))

Роди из Аргентины
источник
-1

Вы можете сделать это таким образом.

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

Вы можете решить вашу проблему таким образом, но использование 'try / Кроме блока' не является лучшей практикой для Python.

Айеш Вирасингхе
источник