[Tutor] Working with lists

Richard Lovely roadierich at googlemail.com
Sat Dec 13 17:49:20 CET 2008


When you need indexes for a list you're iterating over, you want to
look at the function enumerate(), which returns an iterator yielding
(key, value) tuples.

If you're working with multiple lists, itertools.imap and
itertools.imap_longest are handy if you want to keep the lists in
lockstep:

>>> l1 = [1,2,3,4,5]
>>> l2 = ['a','b','c','d','e','f']
>>> for key, value in enumerate(l1):
>>>     print key, value
0 1
1 2
2 3
3 4
4 5
>>> import itertools
>>> for i1, i2 in itertools.izip(l1, l2):
>>>     print i1, i2
1 'a'
2 'b'
3 'c'
4 'd'
5 'e'
>>> for i1, i2 in intertools.izip_longest(l1, l2, fillvalue=0):
>>>     print i1, i2
1 'a'
2 'b'
3 'c'
4 'd'
5 'e'
0 'f'

Preventing yourself from using invalid indexes is harder, and depends
on exactly what you want to happen to the last value in the source
list.  To skip that last value, you could use something like the
following:
if value == longest_list[-1]:
    break

using -1 as an index will always return the last value of that list.
Passing a unique value to fillvalue on izip_longest is another way.  I
normally use a specially created class:

class EndOfList(object):
    pass

then you do:
for values in izip_longest(l1, l2... fillvalue=EndOfList)
    if EndOfList in values: # one of the lists has run out of values
        # do something special, then
        break

And another way of doing your first example, that's one of the
extremly useful tools in python's armoury:

newlist = [a+b for a,b in itertools.izip(l1[:-1], l1[1:])]
This is a list comprehension, and is a very useful tool when you want
to build a list from another list (or any other iterable).  The
'slices' each give you a list with one less item, the first missing
the last item, the second, the first item.

Hope there's the information somewhere in this somewhat jumbled
response to help you.


Richard "Roadie Rich" Lovely, part of the JNP|UK Famile
www.theJNP.com



2008/12/13  <btkuhn at email.unc.edu>:
> Hi everyone,
>
> I seem to use this pattern alot when writing functions and I'm wondering if
> there is a more efficient method. It comes up whenever I want to work with
> more than one item in a list; for instance, say I want to add each
> consecutive number in alist and output the new list. Ideally, I'd be able to
> write:
>
> for num in list1:
> newlist.append(num+nextnum)
>
> This doesn't work, though because there's no way to access "nextnum" unless
> I implement a "count" variable like this:
>
> count=1
> for num in list1:
> newlist.append(num+list1[count])
> count+=1
>
> Instead, it usually ends up easier to write:
>
> for index in range (len(list1)-1):
> newlist.append((list1[index]+list1[index+1]))
>
> It's not a big deal to have to write the additional code, but problems arise
> when I use this structure in the context of more complex functions, when I
> am passing multiple lists of varying length, because it is easy to get
> confused with the index numbers and I can't do anything to the last value of
> the list, since I then get an "indexerror" because the function tries to
> call "list[i+1]".
>
> Is there a simpler way to do a procedure like this?
>
> Thanks.
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>


More information about the Tutor mailing list