问题描述
简单的问题不确定是什么问题但是:我试图遍历两个从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!
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']
当然,它会打印第1行x次,其中x是len(desired_cols_2)。 这不是你用嵌套for循环尝试的吗?
2楼
在任何编程语言中使用for循环都要注意的一件事是迭代10次你很简单地说在for循环中执行相同的语句/函数直到循环结束
for i in ['a','b','c','d']:
for j in ["hello"]:
print(j)
产量
hello
hello
hello
hello
因此,您可以通过在第二个for循环开始之前放置print语句来阻止重复
for row1 in (list(desired_cols_1)):
print row1
for row2 in (list(desired_cols_2)):
3楼
问题是你正在为你的内循环使用一个生成器。
一旦迭代生成器一次 ,生成器就为空 。
因此,在第一个循环中,您将使用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
循环之后它也是空的。
这就是你所看到的。
解决方案是在循环之前创建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
这将仅消耗生成器一次。
或者,如果数据太大,则无法将其全部加载到内存中,您可以为每次迭代创建一个新生成器,而不是在循环之前创建内部生成器:
desired_cols_1 = (list(row[col]) for col in cols_desired) for row in reader1)
for row1 in desired_cols_1:
# Need to make sure the reader is back at the beginning
reader2.seek(0)
desired_cols_2 = (list(row[col]) for col in cols_desired) for row in reader2)
for row2 in desired_cols_2:
print row1, row2