[Tutor] Eek, help!

Danny Yoo dyoo at hkn.eecs.berkeley.edu
Thu Nov 4 20:24:06 CET 2004


> I have belatedly come to use dictionaries, and I was having some
> trouble with how to read/write them from a file,  so I looked at Alan
> Gauld's section on it. I've pretty much copied his code straight
> through, and, well, I've broken it somehow. In fact, it's hanging
> Python, and it even hangs the debugger, which is a first, I must
> admit.

Hi Liam,

Whenever I hear something about a "hang", I almost immediately look at
while loop conditions.  *grin* Let's take a look:



> store2 = file(filename,'r')
>
> while store2:
>     name = store2.readline().strip()
>     entry = store2.readline().strip()
>     book[name] = entry


The while loop here needs to be fixed: store2 is a file, and files are
true values, no matter what.  This is an infinite loop.


What you wanted to say, I think, was to keep the loop running as long as
there's still content in store2.  When we read the end of a file, we'll
get the empty string from a readline.  So one way to correct the loop may
be:

###
while True:
    name, entry = store2.readline(), store2.readline()
    if not name or not entry: break
    name, entry = name.strip(), entry.strip()
    book[name] = entry
###

This is a little more verbose, and might look weird at first, with the
'while True' thing.

The input is not exactly single-line oriented --- you're reading pairs of
lines at a time --- so it complicates matters slightly.



Hmmm... We can make the code a little nicer by pairing up adjacent lines.
Here's a small utility function that may help:

###
def groupAdjacentElements(someSequence, n = 2):
    """A little helper utility to group up adjacent elements."""
    nextGroup = []
    for element in someSequence:
        nextGroup.append(element)
        if len(nextGroup) == n:
            yield tuple(nextGroup)
            nextGroup = []
###

This bit of code will pair up adjacent elements, like this:

###
>>> for a, b in groupAdjacentElements(range(20)):
...     print a, b,  a * b
...
0 1 0
2 3 6
4 5 20
6 7 42
8 9 72
10 11 110
12 13 156
14 15 210
16 17 272
18 19 342
###




With this helper, now the code that reads store2 can be written as a nice
'for' loop instead of the 'while' loop:

###
store2 = file(filename,'r')

for (name, entry) in groupAdjacentElements(store2):
    name = name.strip()
    entry = entry.strip()
    book[name] = entry

store2.close()
###



I hope this helps!



More information about the Tutor mailing list