Python map emptied after using tuple or iteration

Question:

The following code does not print anything from the for loop; it only prints the result of the tuple. This is very unintuitive because I haven’t explicitly modified the cheapest map, yet it behaves as if it is empty after calling tuple.

So, what’s going on?

store1 = [10.00, 11.00, 12.34, 2.34]
store2 = [9.00, 11.10, 12.34, 2.01]
cheapest = map(min, store1, store2)

print(tuple(cheapest))

for v in cheapest: 
    print(v) 

Expected output:

(9.0, 11.0, 12.34, 2.01)
9.0
11.0
12.34
2.01

Actual output:

(9.0, 11.0, 12.34, 2.01)

If I run the for loop first, then the behavior is reversed: the for loop prints the values from the cheapest map and the print(tuple(cheapest)) result is empty as in:

Actual output (order reversed):

9.0
11.0
12.34
2.01
()
Asked By: Austin

||

Answers:

When learning Python you’ll need to pay close attention to the return type of various functions, as many, like map, actually return an iterator1.

While an iterator can be efficient as it is only evaluated if necessary, it can lead to confusion like this where your data is suddenly "gone".

If you need to capture that result before using it in multiple locations, convert it into a more permanent form, like:

cheapest = list(map(min, store1, store2))

Where that can still be used in a for since it’s iterable.


1 In Ruby this is like map { ... }.lazy being enabled by default. In Rust it’s very similar to Python, a map() must be captured with collect() before it’s anything other than an iterator. If you’re used to things like JavaScript where it just dumps out an array, it’ll require a bit of re-learning.

Answered By: tadman
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.