0

The return value of the map function in Python 3 is an Iterator.

Why can the reduce function use the map result, when it needs an Iterable?

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import reduce
def fn(x, y):
  return x * 10 + y
def char2num(s):
   digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
   return digits[s]
reduce(fn, map(char2num, '13579'))
Blckknght
  • 100,903
  • 11
  • 120
  • 169
fischer
  • 3
  • 3
  • 1
    You can pass the return value of `map` to `reduce` because an iterator is an iterable. Iterable just means "you can call `iter` on it". If you call `iter` on an iterator, you'll get the same iterator back again. Please include your example code *as text*, not as an image. It's much easier to view and interact with text (for instance, I can copy and past it into my own interpreter). – Blckknght Aug 21 '18 at 03:55
  • 1
    You may be interested in the answers to this highly voted question on the distinctions between iterators and iterables: https://stackoverflow.com/questions/9884132/what-exactly-are-iterator-iterable-and-iteration I personally prefer my answer to this somewhat worse and now closed question (but of course I'm biased): https://stackoverflow.com/questions/40323783/methods-that-take-iterators-instead-of-iterables – Blckknght Aug 21 '18 at 04:10

1 Answers1

0

The reduce function can consume the iterator returned by map because an iterator is an iterable object. All iterators have an __iter__ method that returns the iterator itself. That's all you need to be iterable (an __iter__ method that returns an iterator, though you can instead get by with a __getitem__ method in some cases).

That said, a few people will be careless of their terminology and use the term iterable when an iterator won't do (perhaps because they need to iterate on the same input several times). There's unfortunately not a single precise name for that subset of iterables (though sequence is often appropriate).

The Python documentation is usually pretty good about this though. If it says a function expects an iterable, and iterator should always be acceptable. If a function or method needs to iterate over the input multiple times (as for instance, str.join does), it will build its own temporary sequence internally if the input isn't already of an acceptable type.

Blckknght
  • 100,903
  • 11
  • 120
  • 169