loop for inside lambda - python

I need to simplify my code as much as possible: it needs to be one line of code.
I need to put a for loop inside a lambda expression, something like that:
x = lambda x: (for i in x : print i)

Just in case, if someone is looking for a similar problem...
Most solutions given here are one line and are quite readable and simple. Just wanted to add one more that does not need the use of lambda(I am assuming that you are trying to use lambda just for the sake of making it a one line code).
Instead, you can use a simple list comprehension.
[print(i) for i in x]
BTW, the return values will be a list on None s.

Since a for loop is a statement (as is print, in Python 2.x), you cannot include it in a lambda expression. Instead, you need to use the write method on sys.stdout along with the join method.
x = lambda x: sys.stdout.write("\n".join(x) + "\n")

To add on to chepner's answer for Python 3.0 you can alternatively do:
x = lambda x: list(map(print, x))
Of course this is only if you have the means of using Python > 3 in the future... Looks a bit cleaner in my opinion, but it also has a weird return value, but you're probably discarding it anyway.
I'll just leave this here for reference.

anon and chepner's answers are on the right track. Python 3.x has a print function and this is what you will need if you want to embed print within a function (and, a fortiori, lambdas).
However, you can get the print function very easily in python 2.x by importing from the standard library's future module. Check it out:
>>>from __future__ import print_function
>>>
>>>iterable = ["a","b","c"]
>>>map(print, iterable)
a
b
c
[None, None, None]
>>>
I guess that looks kind of weird, so feel free to assign the return to _ if you would like to suppress [None, None, None]'s output (you are interested in the side-effects only, I assume):
>>>_ = map(print, iterable)
a
b
c
>>>

If you are like me just want to print a sequence within a lambda, without get the return value (list of None).
x = range(3)
from __future__ import print_function # if not python 3
pra = lambda seq=x: map(print,seq) and None # pra for 'print all'
pra()
pra('abc')

lambda is nothing but an anonymous function means no need to define a function like def name():
lambda <inputs>: <expression>
[print(x) for x in a] -- This is the for loop in one line
a = [1,2,3,4]
l = lambda : [print(x) for x in a]
l()
output
1
2
3
4

We can use lambda functions in for loop
Follow below code
list1 = [1,2,3,4,5]
list2 = []
for i in list1:
f = lambda i: i /2
list2.append(f(i))
print(list2)

First of all, it is the worst practice to write a lambda function like x = some_lambda_function. Lambda functions are fundamentally meant to be executed inline. They are not meant to be stored. Thus when you write x = some_lambda_function is equivalent to
def some_lambda_funcion():
pass
Moving to the actual answer. You can map the lambda function to an iterable so something like the following snippet will serve the purpose.
a = map(lambda x : print(x),[1,2,3,4])
list(a)

If you want to use the print function for the debugging purpose inside the reduce cycle, then logical or operator will help to escape the None return value in the accumulator variable.
def test_lam():
'''printing in lambda within reduce'''
from functools import reduce
lam = lambda x, y: print(x,y) or x + y
print(reduce(lam,[1,2,3]))
if __name__ =='__main__':
test_lam()
Will print out the following:
1 2
3 3
6
You can make it one-liner.

Sample
myList = [1, 2, 3]
print_list = lambda list: [print(f'Item {x}') for x in list]
print_list(myList)
otherList = [11, 12, 13]
print_list(otherList)
Output
Item 1
Item 2
Item 3
Item 11
Item 12
Item 13

Related

How to iterate through a list with a value from a dictionary

I have a list with different values and a dictionary with different equations. I want to iterate with a for-loop through the list values and calculate a given equation. The example is below:
list = [1,2,3,4,5]
d ={"equation1": 2*x+3,
"equation2": 3+4*x}
for x in list:
y= d["equation1"]
print(y)
the output is as you can see below:
5
5
5
5
5
When I put the dictionary into the forloop like the sample below, the right values are calculated:
list = [1,2,3,4,5]
for x in list:
d ={"equation1": 2*x+3,
"equation2": 3+4*x}
y= d["equation1"]
print(y)
Result:
5
7
9
11
13
How can I realise the right results with the dictionary outside the for-loop?
In your first example:
list = [1,2,3,4,5]
d ={"equation1": 2*x+3,
"equation2": 3+4*x}
This can only work if you somehow defined x previously, so you probably didn't share all of your relevant code.
Something like 2*x+3 gets evaluated immediately, so if x == 1, you'd get the result 5, as you suggest you do.
You could create a dict with lambda expressions:
d ={"equation1": lambda x: 2*x+3,
"equation2": lambda x: 3+4*x}
But I wouldn't recommend it as good code. If you do though, this works:
list = [1,2,3,4,5]
d ={"equation1": lambda x: 2*x+3,
"equation2": lambda x: 3+4*x}
for x in list:
y = d["equation1"](x)
print(y)
Note how on the line y = d["equation1"](x) x gets passed to the function accessed with d["equation1"] - a lambda expression is a simple function and the ones defined in the dict expect a single parameter.
A more appropriate solution would be:
def equation1(x):
return 2*x+3
def equation2(x):
return 3+4*x
xs = [1,2,3,4,5]
for x in xs:
y = equation1(x)
print(y)
And then if you have reason to refer to your functions with a dict from somewhere:
xs = [1,2,3,4,5]
funs = {
'equation1': equation1,
'equation2': equation2
}
for x in xs:
y = funs['equation1'](x)
print(y)
The problem you have is that the expressions 2*x+3 and 3+4*x aren't something you can store in a dictionary. Rather, they get computed immediately, with whatever value of x is available when the dictionary is created. They do not use the value of x when the value gets looked up later.
If you want to store some code, like those expressions, to be run later, the natural way to do it in Python is using a function. The lambda keyword even lets you create functions that only evaluate a single expression, which is exactly what you want.
Try:
d = {"equation1": lambda: 2*x+3,
"equation2": lambda: 3+4*x}
for x in list:
d ={"equation1": 2*x+3,
"equation2": 3+4*x}
y = d["equation1"]() # note, here we're calling the lambda function
print(y)
A few other notes:
It might make sense to use a different container than a dictionary for d, since your equation names don't appear to have a great deal of meaning. If you just want to index them by integer (e.g. 1 instead of "equation1"), a list is a much more natural choice.
Also, your equations currently pick the x value freely out of the enclosing namespace. It might be cleaner to pass in the x value as an argument to the lambda function. Grismar's very nice answer covers how to do this for x, so I won't give any redundant example code. Passing the values the equation needs as arguments does require a stricter "contract" to be established between the calling code and the equations though, as if one equation expects there to be a y or z variable defined, you need to know to pass it in as an argument.

Misunderstanding of python 3 map [duplicate]

primes = [2,3,5,7..] (prime numbers)
map(lambda x:print(x),primes)
It does not print anything.
Why is that?
I've tried
sys.stdout.write(x)
too, but doesn't work either.
Since lambda x: print(x) is a syntax error in Python < 3, I'm assuming Python 3. That means map returns a generator, meaning to get map to actually call the function on every element of a list, you need to iterate through the resultant generator.
Fortunately, this can be done easily:
list(map(lambda x:print(x),primes))
Oh, and you can get rid of the lambda too, if you like:
list(map(print,primes))
But, at that point you are better off with letting print handle it:
print(*primes, sep='\n')
NOTE: I said earlier that '\n'.join would be a good idea. That is only true for a list of str's.
This works for me:
>>> from __future__ import print_function
>>> map(lambda x: print(x), primes)
2
3
5
7
17: [None, None, None, None]
Are you using Python 2.x where print is a statement, not a function?
Alternatively, you can unpack it by putting * before map(...) like the following
[*map(...)]
or
{*map(...)}
Choose the output you desire, a list or a dictionary.
Another reason why you could be seeing this is that you're not evaluating the results of the map function. It returns a generator (an iterable) that evaluates your function lazily and not an actual list.
primes = [2,3,5,7]
map(print, primes) # no output, because it returns a generator
primes = [2,3,5,7]
for i in map(print, primes):
pass # prints 2,3,5,7
Alternately, you can do list(map(print, primes)) which will also force the generator to be evaluated and call the print function on each member of your list.

Use print inside lambda

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?
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
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
Why map(print, a_list) doesn't work?
Print doesnt print when it's in map, Python
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'
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.

Python: how to create a function pointer with a set argument?

My problem:
Given the following:
def foo(a,b)
I am trying to call the python 'map' function while passing in a list for 'a' but use a set value for 'b.'
Another relevant fact is that 'b' is user input and thus, I cannot use the syntax:
def foo(a,b='default value')
I want my 'map' call to look like this:
map(foo_wrapper,list_for_a)
where 'foo_wrapper' is some function that takes in 'a' but uses the user specified 'b.'
I don't know whether function pointers can be specified this way and suspect that they cannot.
My solution to this problem uses globals, so if there's a more elegant way and the above is impossible, I will mark that as the answer as well.
Here is my solution in a nutshell:
b = ''
def foo(a,b):
print b,a
def foo_wrapper(a):
foo(a,b)
def main():
if sys.argv[1]:
a = ['John', 'Jacob', 'Jingle all the way']
global b
b = sys.argv[1]
map(foo_wrapper,a)
There may be a typo or two in the above; I am simplifying the problem from what I actually need to do.
Thanks for the replies!
You can use functools.partial() for this purpose:
from functools import partial
def f(a, b):
return a + b
x = range(10)
print map(partial(f, b=3), x)
prints
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
You want something akin to currying. You can just use lambda here:
map(lambda x: f(x,3), a)
Use a list comprehension or a generator expression
[f(x, your_set) for x in your_list]
If you don't need a list as a result, but just a lazy evaluated iterator, you can use a generator expression (or if you meant Python 3's map).
(f(x, your_set) for x in your_list)
Edit:
For your functions that would be:
L = ['John', 'Jacob', 'Jingle all the way']
[foo(a, b=b) for a in L]
List comprehensions are a syntax sugar to replace uses of map with lambda. If you have one of the following:
L2 = map(lambda arg: f(arg) + arg, L1)
L2 = map(lambda (x,y): x + y, L1)
L2 = map(lambda <arg>: <expression>, L1)
They can be rewritten as list comprehensions:
L2 = [f(arg) + arg for arg in L1]
L2 = [x + y for x, y in L1]
L2 = [<expression> for <arg> in L1]
Generator expressions are similar, but instead of a list they return a lazy iterator, and are written with parens instead of square brackets. (And because map in Python 3 is changed to not return lists, there its equivalent is a generator expression.) Sometimes a list is not need, for example when you want to do:
','.join(map(lambda x: x.upper(), L))
The equivalent list comprehension is:
','.join([x.upper() for x in L])
But you actually don't need a list, so you can simply do:
','.join(x.upper() for x in L)

Python: Nested Loop

Consider this:
>>> a = [("one","two"), ("bad","good")]
>>> for i in a:
... for x in i:
... print x
...
one
two
bad
good
How can I write this code, but using a syntax like:
for i in a:
print [x for x in i]
Obviously, This does not work, it prints:
['one', 'two']
['bad', 'good']
I want the same output. Can it be done?
List comprehensions and generators are only designed to be used as expressions, while printing is a statement. While you can effect what you're trying to do by doing
from __future__ import print_function
for x in a:
[print(each) for each in x]
doing so is amazingly unpythonic, and results in the generation of a list that you don't actually need. The best thing you could do would simply be to write the nested for loops in your original example.
Given your example you could do something like this:
a = [("one","two"), ("bad","good")]
for x in sum(map(list, a), []):
print x
This can, however, become quite slow once the list gets big.
The better way to do it would be like Tim Pietzcker suggested:
from itertools import chain
for x in chain(*a):
print x
Using the star notation, *a, allows you to have n tuples in your list.
>>> a = [("one","two"), ("bad","good")]
>>> print "\n".join(j for i in a for j in i)
one
two
bad
good
>>> for i in a:
... print "\n".join(i)
...
one
two
bad
good
import itertools
for item in itertools.chain(("one","two"), ("bad","good")):
print item
will produce the desired output with just one for loop.
The print function really is superior, but here is a much more pythonic suggestion inspired by Benjamin Pollack's answer:
from __future__ import print_function
for x in a:
print(*x, sep="\n")
Simply use * to unpack the list x as arguments to the function, and use newline separators.
You'll need to define your own print method (or import __future__.print_function)
def pp(x): print x
for i in a:
_ = [pp(x) for x in i]
Note the _ is used to indicate that the returned list is to be ignored.
This code is straightforward and simpler than other solutions here:
for i in a:
print '\n'.join([x for x in i])
Not the best, but:
for i in a:
some_function([x for x in i])
def some_function(args):
for o in args:
print o

Categories