Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a function which takes iterable as parameter always accept iterator?

I know iterator is iterable, but only 1 pass.

For example, many functions in itertools take iterable as parameter, e.g islice. Can I always pass in iterator if I see the api says iterable?

As @delnan pointed out:

Although every iterator is an iterable, some people (outside the core team) say "iterable" when they mean "something that can be iterated several times with with the same results". Some code in the wild claims to work on iterables but actually doesn't work with iterators.

That is exact my concern. Is there a name for those iterable which support multipass? Like IEnumerable in C#?

If I am to build a function which claims to support iterable, is it best practice to actually support iterator as well?

like image 834
colinfang Avatar asked Oct 28 '13 19:10

colinfang


2 Answers

Yes, the functions in itertools are designed for use with iterators. The reason why the function signatures say iterable is because they also work on lists, tuples, and other iterables which are not iterators.


A sequence is an iterable which supports efficient element access using integer indices via the __getitem__() special method and defines a len() method that returns the length of the sequence.

This definition is slightly different than the set of all iterables which are not iterators. (You could define a (crippled) custom class which has a __getitem__, method but not a __len__. It would be an iterable which is not an iterator -- but neither would it be a sequence.)

However sequences is pretty close to what you are looking for, since all sequences are iterables which can be iterated over multiple times.

Examples of sequence types built into Python include str, unicode, list, tuple, bytearray, buffer and xrange.


Here are some definitions culled from the glossary:

container
    Has a __contains__ method

generator
    A function which returns an iterator.

iterable
    An object with an __iter__() or __getitem__() method. Examples of
    iterables include all sequence types (such as list, str, and
    tuple) and some non-sequence types like dict and file. When an
    iterable object is passed as an argument to the builtin function
    iter(), it returns an iterator for the object. This iterator is
    good for one pass over the set of values.

iterator
    An iterable which has a next() method.  Iterators are required to
    have an __iter__() method that returns the iterator object
    itself. An iterator is good for one pass over the set of values.

sequence
    An iterable which supports efficient element access using integer
    indices via the __getitem__() special method and defines a len()
    method that returns the length of the sequence. Note that dict
    also supports __getitem__() and __len__(), but is considered a
    mapping rather than a sequence because the lookups use arbitrary
    immutable keys rather than integers.  sequences are orderable
    iterables.

    deque is a sequence, but collections.Sequence does not recognize
    deque as a sequence.
    >>> isinstance(collections.deque(), collections.Sequence)
    False
like image 195
unutbu Avatar answered Nov 15 '22 00:11

unutbu


Yes, because every iterator is also an iterable.

An object is iterable if it defines the __iter__() method. Every iterator has this method, it returns the iterator itself.

like image 20
flornquake Avatar answered Nov 15 '22 00:11

flornquake