msb
msb

Reputation: 4428

How to loop twice over a list in Python

I have a string containing CSV content. I turned it into a list like so:

from StringIO import StringIO
import csv

f = StringIO(list_csv)
my_list = csv.reader(f, delimiter=',')

Now I want to loop twice over the list, but the second time I try to loop, the code goes through as if the list was empty:

for item in my_list:
    code = item[1]
    print "code: "+code

for item in my_list:
    desc = item[2]
    print "desc: "+desc

(this code is simplified for demonstration purposes, I can't combine execution in a single loop)

I figured the list is still attached to the StringIO, and when it's done looping it's done reading, so it won't read again. Is there a one-liner to transform that into a regular list in the memory, that I could loop several times? I feel like running a loop manually copying values is reinventing the wheel.... but I can do that if there's no other option. Just asking for something less lengthy code-wise. Thanks!

Upvotes: 2

Views: 5441

Answers (3)

Menglong Li
Menglong Li

Reputation: 2255

Use tee function in itertools, which can provide you more accesses into the iterator, not just once.

from itertools import tee

i1, i2 = tee(my_list)

for i in i1:
    pass

for i in i2:
    pass

Upvotes: 0

Nitin Prabhakar
Nitin Prabhakar

Reputation: 1

use this the following code:

my_list = list(csv.reader(f, delimiter=','))

Upvotes: 0

Rick
Rick

Reputation: 45231

The problem is that my_list is not actually a list. It is an iterator (actually a reader object in this particular case, which is just a type of iterator).

An iterator is consumed after the first time all the values have been yielded. This is what is happening to mylist: after the first time you loop through it, the reader object has already been consumed and cannot be iterated again.

One solution is to store the contents in an actual list object. This should fix it:

my_list = list(csv.reader(f, delimiter=','))

...then proceed as before.

By the way if you are using a recent version of Python 3, there's a really nice syntax available for unpacking the iterator to a list:

my_list = [*csv.reader(f, delimiter=',')]

Upvotes: 6

Related Questions