title: What is the 2nd argument for the iter function in Python?
body: <p>Let's consider a file:</p>
  
  <pre><code>$ echo -e """This is a foo bar sentence .\nAnd this is the first txtfile in the corpus .""" &gt; test.txt
  $ cat test.txt 
  This is a foo bar sentence .
  And this is the first txtfile in the corpus .
  </code></pre>
  
  <p>And when I want to read the file by character, I can do <a href="https://stackoverflow.com/a/25071590/610569">https://stackoverflow.com/a/25071590/610569</a>:</p>
  
  <pre><code>&gt;&gt;&gt; fin = open('test.txt')
  &gt;&gt;&gt; while fin.read(1):
  ...     fin.seek(-1,1)
  ...     print fin.read(1),
  ... 
  T h i s   i s   a   f o o   b a r   s e n t e n c e   . 
  A n d   t h i s   i s   t h e   f i r s t   t x t f i l e   i n   t h e   c o r p u s   .
  </code></pre>
  
  <p>But using while loop might look a little unpythonic esp. when i use <code>fin.read(1)</code> to check for EOF and then backtrack in-order to read the current byte. And so I can do something like this <a href="https://stackoverflow.com/q/2988211/610569">How to read a single character at a time from a file in Python?</a>:</p>
  
  <pre><code>&gt;&gt;&gt; import functools
  &gt;&gt;&gt; fin = open('test.txt')
  &gt;&gt;&gt; fin_1byte = iter(functools.partial(fin.read, 1), '')
  &gt;&gt;&gt; for c in fin_1byte:
  ...     print c,
  ... 
  T h i s   i s   a   f o o   b a r   s e n t e n c e   . 
  A n d   t h i s   i s   t h e   f i r s t   t x t f i l e   i n   t h e   c o r p u s   .
  </code></pre>
  
  <p>But when I tried it without the second argument, it throws a <code>TypeError</code>:</p>
  
  <pre><code>&gt;&gt;&gt; fin = open('test.txt')
  &gt;&gt;&gt; fin_1byte = functools.partial(fin.read, 1)
  &gt;&gt;&gt; for c in iter(fin_1byte):
  ...     print c,
  ... 
  Traceback (most recent call last):
    File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  TypeError: 'functools.partial' object is not iterable
  </code></pre>
  
  <p><strong>What is the 2nd argument in <code>iter</code>?</strong> The docs don't say much either: <a href="https://docs.python.org/2/library/functions.html#iter" rel="nofollow noreferrer">https://docs.python.org/2/library/functions.html#iter</a> and <a href="https://docs.python.org/3.6/library/functions.html#iter" rel="nofollow noreferrer">https://docs.python.org/3.6/library/functions.html#iter</a></p>
  
  <hr>
  
  <p>As per the doc:</p>
  
  <blockquote>
    <p>Return an iterator object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, object must be a collection object which supports the iteration protocol (the <strong>iter</strong>() method), or it must support the sequence protocol (the <strong>getitem</strong>() method with integer arguments starting at 0). If it does not support either of those protocols, TypeError is raised. If the second argument, sentinel, is given, then object must be a callable object. The iterator created in this case will call object with no arguments for each call to its <strong>next</strong>() method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.</p>
  </blockquote>
  
  <p>I guess the docs require some "decrypting":</p>
  
  <ul>
  <li>Without a second argument, object must be a collection object which supports the iteration protocol (the <strong>iter</strong>() method)</li>
  </ul>
  
  <p>Does that mean it needs to come from <code>collections</code>? Or is that as long as the object has an <code>__iter__()</code>, that's okay?</p>
  
  <ul>
  <li>, or it must support the sequence protocol (the <strong>getitem</strong>() method with integer arguments starting at 0)</li>
  </ul>
  
  <p>That's rather cryptic. So does that means it tries to see whether the sequence is indexed and hence query-able and that the index must starts from 0? Does it also mean that the indices need to be sequential, i.e. 0, 1, 2, 3, ... and not something like 0, 2, 8, 13, ...?</p>
  
  <ul>
  <li>If it does not support either of those protocols, TypeError is raised.</li>
  </ul>
  
  <p>Yes, this part, I do understand =)</p>
  
  <ul>
  <li>If the second argument, sentinel, is given, then object must be a callable object.</li>
  </ul>
  
  <p>Okay, now this gets a little sci-fi. Is it just a terminology in Python to call something a <code>sentinel</code>? What does <code>sentinel</code> mean Pythonically? And "callable object" like it's a function and not type object? </p>
  
  <ul>
  <li>The iterator created in this case will call object with no arguments for each call to its next() method; </li>
  </ul>
  
  <p>This part i don't really get it, maybe an example would help.</p>
  
  <ul>
  <li>if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.</li>
  </ul>
  
  <p>Okay, so <code>sentinel</code> here refers to some breaking criteria? </p>
  
  <p><strong>Can someone help to decipher/clarify the meaning of the above points about <code>iter</code>?</strong> </p>