5

Example:

for x in iterable1:
    expression

The map form would be:

map(lambda x: expression, iterable1)

How do I extend this to a nested for loop using only map and without list comprehensions?

Example:

for x in itr1:
    for y in itr2:
        expr
Georgy
  • 12,464
  • 7
  • 65
  • 73
lapin
  • 432
  • 1
  • 5
  • 11

3 Answers3

6

You could use itertools.product to build the cartesian product of your two nested sequences, and map your expression to the that list of 2-tuples:

from itertools import product

map(lambda (x, y): expression, product(itr1, itr2))

Example with some actual values:

seq = map(lambda (x, y): '%s:%s' % (x, y), product(itr1, itr2))
for item in seq:
    print item

Note that the lambda (x, y) is necessary to unpack each 2-tuple from the sequence to the separate x and y arguments used in the expression.

Lukas Graf
  • 30,317
  • 8
  • 77
  • 92
  • This works but not what I had in mind, and you code eliminate seq by just using print inside the lambda (expression statement). I read in 'Learning Python by Mark Lutz', that, 'The map and filter equivalent of this last example would be wildly complex and deeply nested so I won't even try showing it here.' – lapin May 24 '16 at 16:22
  • You can't use statements inside expressions. The `print` is just for demonstration purposes. Having said that, this still addresses your question, unless you're asking about *only using `map`* - then the answer is "you can't". – Lukas Graf May 24 '16 at 16:25
  • Apart from the use of list I think I did it only using map. The list is for the iteration protocol. @Lukas Graf – lapin May 27 '16 at 04:16
  • This doesn't work if `itr2` is depended to `itr1`. Like `x+1 for x in i1 for y in x` for example. – Mohammad Jafari Jan 26 '22 at 08:47
2

Bear with me on this one. Not an explanation but this worked after 2 days. Using only map and list. It's bad code. Suggestions to shorten the code are welcome. Python 3 solution

Example using list comprehension:

>>> a=[x+y for x in [0,1,2] for y in [100,200,300]]
>>> a
[100,200,300,101,201,301,102,202,302]

Example using for:

>>>a=[]
>>>for x in [0,1,2]:
...    for y in [100,200,300]:
...        a.append(x+y)
...
>>>a
[100,200,300,101,201,301,102,202,302]

Now example using only map:

>>>n=[]
>>>list(map(lambda x:n.extend(map(x,[100,200,300])),map(lambda x:lambda y:x+y,[0,1,2])))
>>>n
[100,200,300,101,201,301,102,202,302]

Much smaller python2.7 solution:

>>>m=[]
>>>map(lambda x:m.extend(x),map(lambda x:map(x,[100,200,300]),map(lambda x:lambda y:x+y,[0,1,2])))
>>>m
[100,200,300,101,201,301,102,202,302]

Another variation : I emailed to Mark Lutz and this was his solution. This doesn't use closures and is the closest to nested for loops functionality.

>>> X = [0, 1, 2]               
>>> Y = [100, 200, 300]
>>> n = []
>>> t = list(map(lambda x: list(map(lambda y: n.append(x + y), Y)),X))
>>> n
[100,200,300,101,201,301,102,202,302]
lapin
  • 432
  • 1
  • 5
  • 11
1

You can't. The lambda is specifically limited to functions whose return value can be encapsulated as a single expression: statements aren't allowed.

One question you should ask yourself is why do you think this would be a desirable way to write a Python program? The language has been explicitly defined for readability, and you should do everything you can to maintain that readability.

holdenweb
  • 33,305
  • 7
  • 57
  • 77