Почему печать не работает в лямбде?


164

Почему это не работает?

lambda: print "x"

Это не одно утверждение, или это что-то еще? Документация кажется немного разреженной на том, что разрешено в лямбде ...


1
docs.python.org/reference/expressions.html#lambda . Он говорит «выражение», которое является ссылкой на полное определение всех возможных выражений. Как это "разреженный"? Что было неверным или неполным?
— С.Лотт

3
@ У меня было неправильное представление о том, что такое выражение / утверждение и куда относится печать. это имеет смысл сейчас
— Anycorn

Ответы:


188

А lambdaтело «S должно быть одно выражение . В Python 2.x printэто утверждение. Однако в Python 3 printэто функция (а приложение-функция - это выражение, поэтому оно будет работать в лямбде). Вы можете (и должны для прямой совместимости :) использовать функцию печати с обратным портированием, если вы используете последнюю версию Python 2.x:

In [1324]: from __future__ import print_function

In [1325]: f = lambda x: print(x)

In [1326]: f("HI")
HI

5
Теперь я понимаю, почему это было так важно сделать его функцией. Хотел использовать print в качестве kwarg по умолчанию, и это исправило это. Спасибо.
— Томас Диньян

1
Могу ли я знать, почему from __future__ import print_functionдолжно быть в начале кода? THX
— Бен

Где бы я увидел отпечатки того, что мы здесь написали?
— Sk. Ирфан

Я согласен с комментарием Бена: я не получаю этот импорт. Python (2 или 3) имеет print()встроенный метод.
— ivanleoncz

27

В случаях, когда я использую это для простой заглушки, я использую это:

fn = lambda x: sys.stdout.write(str(x) + "\n")

который работает отлично.


3
Как дополнительное примечание - используйте из будущего выше. Используйте это только там, где это недоступно - что сейчас будет серьезно устаревшей версией.
— Дэнни Стейпл

24

то, что вы написали, эквивалентно

def anon():
    return print "x"

что также приводит к SyntaxError, python не позволяет назначить значение для печати в 2.xx; в python3 можно сказать

lambda: print('hi')

и это будет работать, потому что они изменили print, чтобы быть функцией вместо выражения.


3
Есть также from __future__ import print_function, что позволяет это в py2.x
— tzaman

5
Или в качестве альтернативыlambda: sys.stdout.write('hi')
— Fmark

@fmark: за исключением того, что в 2.x все не так просто: вам нужно обработать sys.stdout.softspace и (по крайней мере) написать после него новую строку.
— Фред Нурк

11

Тело лямбды должно быть выражением, которое возвращает значение. print, Будучи заявление, не возвращает ничего, даже None. Точно так же вы не можете присвоить результат printпеременной:

>>> x = print "hello"
  File "<stdin>", line 1
    x = print "hello"
            ^
SyntaxError: invalid syntax

Вы также не можете поместить переменное присваивание в лямбду, так как присваивания являются операторами:

>>> lambda y: (x = y)
  File "<stdin>", line 1
    lambda y: (x = y)
                 ^
SyntaxError: invalid syntax

11

Вы можете сделать что-то вроде этого.

Создайте функцию для преобразования оператора print в функцию:

def printf(text):
   print text

И распечатать это:

lambda: printf("Testing")

Более гибко:def printf(fmt, *args): print(fmt % args)
— IvyMike

4

В Python 3.x печать МОЖЕТ работать в лямбде, не меняя семантику лямбды.

При специальном использовании это очень удобно для отладки. Я публикую этот «поздний ответ», потому что это практический прием, которым я часто пользуюсь.

Предположим, что ваша «неструктурированная» лямбда это:

lambda: 4

Тогда ваша «инструментальная» лямбда это:

lambda: (print (3), 4) [1]

3

Тело лямбды должно быть единым выражением . printэто утверждение, так что это, к сожалению, нет.


спасибо, я не был уверен в определении выражения по сравнению с утверждением, теперь это имеет смысл
— Anycorn

2

Здесь вы видите ответ на свой вопрос. printэто не выражение в Python, это говорит.


1
Неполный ответ, но приятная ссылка.
— Стивен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.