Python Lambda возвращает None вместо пустой строки

у меня есть следующая функция Lambda:

f = lambda x: x == None and '' or x

Он должен возвращать пустую строку, если она не получает None в качестве аргумента, или аргумент, если это не None.

например:

>>> f(4)
4
>>> f(None)
>>>

Если я вызываю f (None) вместо получения пустой строки, Я не получаю None. Я напечатал тип того, что функция вернула, и я получил NoneType. Я ожидал увидеть стринг.

type (") возвращает строку, поэтому я хотел бы знать, почему лямбда не возвращает пустой string, когда я передаю None в качестве аргумента.

Я довольно новичок в lambdas, поэтому я, возможно, неправильно понял некоторые вещи о том, как они работают.

6 ответов


используйте конструкцию if else

f = lambda x:'' if x is None else x

проблема в вашем случае, что " считается логическим False. bool (") = = False. Вы можете использовать

f =lambda x:x if x is not None else ''

проблема в том, что Python обрабатывает пустую строку как False. Когда вы передаете None своей функции, она вычисляется как:

None == None and '' or None

который (фактически) становится:

True and False or None

затем:

False or None

и наконец:

None

одним из решений может быть:

lambda x: x if x is not None else ''

если вы знаете, что x будет либо строкой, либо None, то вы можете использовать тот факт, что None также является ложным значением в Python:

lambda x: x or ''

Python выдает and более высокий приоритет, чем or, Так что скобки здесь:

lambda x: (x == None and '') or x

при передаче None, это становится (True and '') or None. Логические операторы Python работают, возвращая тот или иной аргумент (откуда этот маленький трюк), поэтому это сводится к '' or None, и окончательно None.

этот маленький трюк проистекает из спины до Python 2.5, у которого не было условный оператор. Оговорка, с которой вы только что столкнулись, заключается в том, что не так, как ожидалось, когда True филиале False значение. Если вы не связаны с Python ≤ 2.4, просто используйте условный оператор.


проблема здесь не в лямбдах. Это pythonic if / else expressiong, который вы используете там.

(condition) and (expression1) or (expression2) в большинстве случаев означает (condition) ? (expression1) : (expression2) вы ожидали бы, за исключением когда expression1 вычисляет значение False.

это потому, что все это оценивается в порядке. Если condition не, expression1 оценивается. Если это True, он возвращается из-за оценки короткого замыкания, следовательно, ожидаемого поведения. Если нет,expression2 возвращается. '' значение Ложный.


попробовать оценка короткого замыкания:

 >>> g = lambda x: x or ''
 >>> g(3)
 3
 >>> g(None)
 ''
 >>> # beware that ...
 >>> g(0)
 ''