4

I am trying to use print inside lambda. Something like that:

lambda x: print x

I understand, that in Python 2.7 print is not a function. So, basically, my question is: Is there a pretty way to use print as function in Python 2.7?

Gurio
  • 147
  • 2
  • 3
  • 12
  • 1
    You have answers telling you how to convert print to a function, but is there a good reason why you don't just write a function instead of a lambda? Then you can have multiple statements and everything. The only cost is that you have to give the function a name. – Duncan Mar 05 '14 at 13:45
  • @Duncan Because, in my case, it is more readable and simpler. For example: map (lambda x: print (x.encode()), sequence) Is much better, than defining a function and then mapping it. – Gurio Mar 06 '14 at 07:40
  • but in that case: `for x in sequence: print(x.encode())` would be so much simpler. Why complicate things? There are times when `lambda` is very useful, but not for that. – Duncan Mar 06 '14 at 10:18
  • @Duncan Well, in fact, they are equal. In my case (I didn't showed that) I am also use array of encoded values later, which map returns. It is a bit strange, but tastes differ ;) – Gurio Mar 07 '14 at 12:01

4 Answers4

10

You can import print_function from the __future__ and use it as a function like this

from __future__ import print_function
map(print, [1, 2, 3])
# 1
# 2
# 3
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
  • Crap, I use 2.7, always include that import, and never realized this way now possible... – RemcoGerlich Mar 05 '14 at 13:13
  • I know the question is for Python 2, but I'd like to do the same in Python 3. I thought `map` would work as well, but the output I get with 3.6.0 for `map(print, [1, 2, 3])` is `` which looks like the iterator itself. Any idea? Your solution runs fine in Python 2. – Taylor D. Edmiston Feb 21 '17 at 19:04
  • It looks like wrapping the map call like this: `[*map(print, [1,2,3])]` successfully prints in 3, but I'd prefer to just print and not return a list of nulls. – Taylor D. Edmiston Feb 21 '17 at 19:08
  • @TaylorEdmiston To think of it now, this is not so pretty. You might want to simply do `for item in [1, 2, 3]: print(item)` – thefourtheye Feb 22 '17 at 11:40
  • 1
    @thefourtheye Thanks! For the project I'm using it in, I'm trying to define this behavior inside a lambda. One option that came to me this morning to do that is using *args inside the print function, like this: `print(*lst, sep='\n')`. I'll add this as a separate answer for others. – Taylor D. Edmiston Feb 22 '17 at 17:55
  • I've added an answer below summarizing what worked for me in Python 3. – Taylor D. Edmiston Feb 22 '17 at 18:40
8

The question is about Python 2, but I ended up here from Google trying to use the print function inside a lambda in Python 3. I'm adding this answer for context for others that come here for the same.

If you only want to see the code that works and not how I arrived there, skip to the last code sample at the bottom. I wanted to clearly document what didn't work for learning purposes.

Desired result

Let's suppose you want to define a lambda print_list that prints each item of a list with a newline in between.

lst = [1, 2, 3]

print_list = lambda lst: ...

The desired output is:

1
2
3

And there should be no unused return value.

Attempt 1 - A map doesn't evaluate the print function in Python 3

To start, here's what doesn't work well in Python 3:

map(print, lst)

However, the output is somewhat counterintuitively not printed lines, because the map call in Python 3 returns an iterator instead of an evaluated list.

Output:

n/a

Return value:

<map at 0x111b3a6a0>

Attempt 2 - Evaluate the map iterator

You can realize the printing by passing the map result to list(...), which produces the ideal output, but has the side effect of returning a list of nulls (as evaluated in the REPL).

list(map(print, lst))

Output:

1
2
3

Return value:

[None, None, None]

You could workaround this by using the underscore throwaway variable convention:

_ = list(map(print, lst))

A similar approach is calling print inside a list comprehension:

[print(i) for i in lst]

I don't love these approaches because they both still generate an unused return value.

Attempt 3 - Apply the unpacking operator to the map iterator

Like this:

[*map(print, [1, 2, 3])]

(This still returns a list of nulls which is non-ideal.)

In the comments above @thefourtheye suggests using a one-line for loop:

for item in [1, 2, 3]: print(item)

This works fine for most cases and avoids the side effect. Attempting to put this in a lambda throws a SyntaxError. I tried wrapping it in parens without success; though there is probably a way to achieve this, I haven't figured it out.

(SOLUTION!) Attempt 4 - Apply the unpacking operator inside of the print call

The answer I arrived at is to explode the list inside the print call alongside using the separator arg:

print(*lst, sep='\n')

Output:

1
2
3

This produces the intended result without a return value.

Finally, let's wrap it up in a lambda to use as desired:

print_list = lambda lst: print(*lst, sep='\n')
print_list([1, 2, 3])

This was the best solution for my use case in Python 3.

Related questions

Taylor D. Edmiston
  • 12,088
  • 6
  • 56
  • 76
4

If you don't want to import from __future__ you can just make the lambda write to the standard output:

>>>import sys
>>>l = lambda x : sys.stdout.write(x)
>>>l('hi')
'hi'
Paulo Bu
  • 29,294
  • 6
  • 74
  • 73
1

I guess there is another scenario people may be interested in: "print out the intermediate step value of the lambda function variables"

For instance, say I want to find out the charset of a collection of char list:

In [5]: instances = [["C","O","c","1","c","c","c","c","c","1","O","C","C","N","C"],
   ...: ["C","C","O","C","(","=","O",")","C","C","(","=","O",")","c"],
   ...: ["C","N","1","C","C","N","(","C","c","2","c","c","c","(","N"],
   ...: ["C","l","c","1","c","c","c","2","c","(","N","C","C","C","["],
   ...: ["C","C","c","1","c","c","c","(","N","C","(","=","S",")","N"]]

one way of doing this is to use reduce:

def build_charset(instances):
    return list(functools.reduce((lambda x, y: set(y) | x), instances, set()))

In this function, reduce takes a lambda function with two variables x, y, which at the beginning I thought it would be like x -> instance, and y -> set(). But its results give a different story, so I want to print their value on the fly. lambda function, however, only take a single expression, while the print would introduce another one.

Inspired by set(y) | x, I tried this one and it worked:

lambda x, y: print(x, y) or set(y) | x

Note that print() is of NoneType, so you cannot do and, xor these kinds of operation that would change the original value. But or works just fine in my case.

Hope this would be helpful to those who also want to see what's going on during the procedure.

Oaklight
  • 11
  • 1