classification
Title: Improve documentation example for using iter() with sentinel value
Type: Stage: resolved
Components: Documentation Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: docs@python Nosy List: ChrisRands, docs@python, rhettinger
Priority: normal Keywords: patch

Created on 2018-09-21 15:41 by ChrisRands, last changed 2018-12-24 16:13 by rhettinger. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 11222 merged ChrisRands, 2018-12-18 21:40
PR 11301 merged miss-islington, 2018-12-24 15:50
Messages (5)
msg325995 - (view) Author: (ChrisRands) * Date: 2018-09-21 15:41
This arose from this SO question: https://stackoverflow.com/questions/52446415/line-in-iterfp-readline-rather-than-line-in-fp 

The example given in the docs:

with open('mydata.txt') as fp:
    for line in iter(fp.readline, ''):
        process_line(line)

Is exactly equivalent to the following because an empty string is only returned by readline at the EOF:

with open('mydata.txt') as fp:
    for line in fp:
        process_line(line)

The empty string '' sentinel value could be changed to another value to provide a possibly more meaningful example where the 2nd code snippet would not always produce the same result?
msg326017 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-09-21 18:56
I concur that the readline() example is problematic.  While it succeeds in showing how iter() works, the example itself is not the best way to solve that particular problem.

Here are two possible substitute examples.

1) Simple example that focuses primarily on the behavior of iter() and required little extra knowledge:


    >>> from random import randint
    >>> def roll_dice():
            return randint(1, 6) + randint(1, 6)

    >>> # roll until a seven is seen
    >>> list(iter(roll_dice, 7))
    >>> list(iter(roll_dice, 7))
    [10, 6, 5, 6, 8]

2) Practical application reading binary files in fixed-width blocks for processing with the structure module.  This also teaches how to partial() to produce an arity-zero callable suitable for use with iter().

    >>> Read fixed-width blocks from a database binary file
    >>> from functools import partial
    >>> with open('mydata.db', 'rb') as f:
    	    for block in iter(partial(f.read, 64)):
		print(parse_struct(block))
msg326045 - (view) Author: (ChrisRands) * Date: 2018-09-21 21:30
Thank you Raymond, I like both your examples, although I think I prefer 1) for the simplicity
msg332473 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-12-24 15:49
New changeset d378b1f8ed7919f65a89f026bc899204be3773d4 by Raymond Hettinger (Chris Rands) in branch 'master':
bpo-34764: improve docs example of iter() with sentinel value (GH-11222)
https://github.com/python/cpython/commit/d378b1f8ed7919f65a89f026bc899204be3773d4
msg332480 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2018-12-24 16:13
New changeset 00a48d57dfd52a968b357d68f63c51db3a451566 by Raymond Hettinger (Miss Islington (bot)) in branch '3.7':
bpo-34764: improve docs example of iter() with sentinel value (GH-11222) (#11301)
https://github.com/python/cpython/commit/00a48d57dfd52a968b357d68f63c51db3a451566
History
Date User Action Args
2018-12-24 16:13:21rhettingersetmessages: + msg332480
2018-12-24 15:50:06miss-islingtonsetpull_requests: + pull_request10536
2018-12-24 15:49:27rhettingersetmessages: + msg332473
2018-12-24 05:20:51rhettingersetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2018-12-18 21:40:38ChrisRandssetkeywords: + patch
stage: patch review
pull_requests: + pull_request10457
2018-09-21 21:30:40ChrisRandssetmessages: + msg326045
2018-09-21 18:56:18rhettingersetnosy: + rhettinger
messages: + msg326017
2018-09-21 15:41:31ChrisRandscreate