当前位置: 代码迷 >> python >> Python嵌套for-in循环 - 最外层循环不迭代 编辑 :更具体地来说,这就是我想要做的事情:(我现在只是打印以尝试诊断问题)
  详细解决方案

Python嵌套for-in循环 - 最外层循环不迭代 编辑 :更具体地来说,这就是我想要做的事情:(我现在只是打印以尝试诊断问题)

热度:42   发布时间:2023-06-13 14:04:34.0

简单的问题不确定是什么问题但是:我试图遍历两个从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!

我认为你需要将生成器放在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循环尝试的吗?

在任何编程语言中使用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)):

问题是你正在为你的内循环使用一个生成器。 一旦迭代生成器一次 ,生成器就为 因此,在第一个循环中,您将使用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