Python嵌套for-in循环 - 最外层循环不迭代

时间:2015-10-19 00:53:30

标签: python csv

简单的问题不确定是什么问题但是:我正在尝试迭代从csv文件中读取的两个列表,如下所示:

for row1 in (list(csv_data1)):
  for row2 in (list(csv_data2)):
    # do something with row2 and row2

然而,在外部for循环的每次迭代之后,内部for循环不会识别外部for循环被迭代!例如,如果我这样做:

for row1 in (list(csv_data1)):
  for row2 in (list(csv_data2)):
    # do something with row2 and row2
  print row1

row1的元素正确打印。但是,如果我尝试在内循环中打印最外层循环的元素,如下所示:

for row1 in (list(csv_data1)):
   for row2 in (list(csv_data2)):
     # do something with row2 and row2
     print row1

我只多次获得(list(csv_data1))的第一行!

因此,如果csv_data1 = [['a','b'],['b','c']],我希望打印上面的print语句(在内循环中打印):

[['a','b']
# repeated prints of above for however long csv_data2 is ...
['b','c']]
# repeated prints of above for however long csv_data2 is ...

但我得到以下内容:

[['a','b']
# repeated prints of above for however long csv_data2 is ...
['a','b']]
# repeated prints of above for however long csv_data2 is ...

即。我不能让两个循环互相迭代。我错过了一些非常明显的东西,任何帮助都将不胜感激。感谢。

修改:更具体地说,这就是我要做的事情:(我现在只是打印以尝试诊断问题)

f1 = open('file1.csv', 'rU')
f2 = open('file2.csv', 'rU')
reader1 = csv.DictReader(f1)
reader2 = csv.DictReader(f2)

# Grab desired columns from csv file
cols_desired = 'district,blockname,villagename'.split(',')

desired_cols_1 = (list(row[col]) for col in cols_desired) for row in reader1)
desired_cols_2 = (list(row[col]) for col in cols_desired) for row in reader2)

for row1 in (list(desired_cols_1)):
  for row2 in (list(desired_cols_2)):
    print row1
    # XXX this prints only the first row of list(desired_cols_1) repeated times for some reason!

3 个答案:

答案 0 :(得分:1)

我认为你需要将生成器放在list_calls_1和_2的列表调用中。

desired_cols_1 = [ [row[col] for col in cols_desired] for row in reader1 ]
desired_cols_2 = [ [row[col] for col in cols_desired] for row in reader2 ]

for row1 in desired_cols_1:
    for row2 in desired_cols_2:
        print row1

我的file_1.csv:

district,blockname,villagename
a,b,c
e,f,g

我的file_2.csv:

district,blockname,villagename
1,1,1
2,2,2
3,3,3

输出:

['a', 'b', 'c']
['a', 'b', 'c']
['a', 'b', 'c']
['e', 'f', 'g']
['e', 'f', 'g']
['e', 'f', 'g']

当然,它会打印row1 x次,其中x是len(desired_cols_2)。这不是你用嵌套for循环尝试的吗?

答案 1 :(得分:1)

在任何编程语言中使用for循环都需要注意的一件事是迭代10次你很简单地说在for循环中执行相同的语句/函数直到循环结束

hello
hello
hello
hello

输出

for row1 in (list(desired_cols_1)):
    print row1   
    for row2 in (list(desired_cols_2)):

因此,您可以通过在第二个for循环开始之前放置print语句来阻止重新发送

{{1}}

答案 2 :(得分:1)

问题是您正在为内循环使用生成器。一旦迭代生成器一次,生成器为空。因此,在第一个循环中,您将使用Vector *VectorRead(void) 的所有元素,然后对于以下所有循环它都是空的。

看看这个:

csv_data2

每次迭代都会创建一个新列表,除了第一次迭代之外,>>> x = (i for i in range(5)) >>> y = (i for i in range(5)) >>> for i in x: ... ylist = list(y) ... print(id(ylist)) ... print(len(ylist)) ... 44917584 5 44917624 0 44918104 0 44918144 0 44918184 0 >>> print(len(list(x))) 0 都是空的。那是因为第一次迭代在创建ylist时消耗生成器的元素。对list有类似的影响:它在x循环后也是空的。这就是你所看到的。

解决方案是在循环中创建for s 之前

list

这只会消耗一次发生器。

或者,如果数据太大,则无法将其全部加载到内存中,您可以为每次迭代创建一个新生成器,而不是在循环之前创建内部生成器:

# Square brackets make this a list comprehension instead of a raw generator
# List comprehension gives back a list
desired_cols_1 = [list(row[col]) for col in cols_desired) for row in reader1]
desired_cols_2 = [list(row[col]) for col in cols_desired) for row in reader2]

for row1 in desired_cols_1:
  for row2 in desired_cols_2:
    print row1, row2