2

我是 python 新手,在实现嵌套的“for 循环”时遇到了困难。这可能很简单,但我尝试的以下示例代码并没有给我预期的结果。我的任务实际上是从属性表(ArcGIS 要素数据)中读取记录,并将其与 CSV 文件中的每条记录进行比较。但最初我试图对 2 个 CSV 文件做同样的事情,然后将类似的逻辑应用于我原来的问题。我试图弄清楚循环的工作原理,稍后我可以添加比较条件。任何帮助是极大的赞赏。谢谢。

这个想法是文件 1(CSV) 中的第一行将自身与文件 2(CSV) 中的所有行(逐行)进行比较,然后文件 1 中的第二行执行相同操作,直到文件 1 的每一行将自身与所有行进行比较文件 2 中的行。因此,在预期的结果中,我试图查看文件 1 中的每一行是否考虑了文件 2 中的每一行。

例子:

**File 1   File 2**
ALPHA      All
BETA       Bell
GAMMA      Cell
DELTA      Dell
ITA 

示例代码:

import csv, sys, os, string 
table1 = os.path.join(path, 'table1.csv')
table2 = os.path.join(path, 'table2.csv')
file1 = csv.reader(open(table1, 'r'))
file2 = csv.reader(open(table2, 'r'))
for row in file1:
    print row
    for prow in file2:
        print prow

预期结果:

   ALPHA
    All
    Bell
    Cell
    Dell

    BETA
    All 
    …..

    ITA

All
..
Dell
4

5 回答 5

3

这里的问题是,这file2只是一个一次性迭代器。因此,在迭代file2一次之后(在 的第一次迭代中file1),您完全耗尽了数据。

相反,您必须将 的内容存储file2在列表中:

file2=list(csv.reader(open(table2,'r')))
for row in file1:
     print row
     for prow in file2:
         print prow

这将为您打印一些列表,所有这些列表仅包含一个元素,即相应行的第一个单元格。这是由于将文件解析为 CSV。每次迭代都会为您提供行中的单元格列表。

于 2012-06-26T15:22:56.933 回答
3

这是因为当您迭代一个csv.reader对象时,每次迭代它都会变为空。

这就是file2迭代器以这种方式表现的原因。

要解决这个问题,您应该首先将值保存file2在列表中。

file1=csv.reader(open(table1,’r’))
file2=list(csv.reader(open(table2, 'r'))) #edited this
for row in file1:
...     print row
...     for prow in file2:
...         print prow
于 2012-06-26T15:23:25.307 回答
1

CSV 模块将为这两个文件返回迭代器,这些文件在循环后将被“使用”。这是文件的典型 Python 行为。

为了将一个文件中的值循环用于另一个文件,您可以将它们加载到内存中。出于对您意图的最佳解读,我假设您希望将一个文件中的数据与另一个文件中的每一行相关联。我将举一个说明性的例子:

greek = csv.reader(open('file1.csv'))
dells = csv.reader(open('file2.csv'))

second_file_data = list(dells)

#From here, dells is "spent."  If we would want to reuse it, we have to reopen it

for line in greek:
  print line
  for other in second_file_data:
      print other
于 2012-06-26T15:22:45.370 回答
1

不要这样做。

将第一个文件读入适当的数据结构(例如 a set),然后在读取第二个文件时,针对数据结构中收集的行进行测试。

对于本练习,最好创建单个字符串,因为您似乎每次都打印从第一个文件读取的全部数据。

file2='\n'.join((l[0] for l in csv.reader(open(table2,’r’))))
for row in file1:
        print row
        print file2

如果需要缩进,可以使用textwrap将缩进添加到file2.

于 2012-06-26T15:23:09.877 回答
1

问题是,在你遍历 file2 的所有行之后,它的流被消耗掉了。没有什么可读的了。Next for 循环不会重新设置 csv.reader 对象,而是识别出所有内容都已被读取和解析,因此无需再做任何事情。

解决方案可能包括:

file2_stream = open(table2, 'r')
for row in file1:
  print row
  file2_stream.seek(0)  # Reset file stream position
  file2 = csv.reader(file2_stream)  # Init CSV parsing
  for prow in file2:
    print prow

或者,您可以每次都重新打开文件:

for row in file1:
  print row
  file2 = csv.reader(open(table2, 'r'))
  for prow in file2:
    print prow

这显然会在每次外部迭代时解析第二个文件。如果文件与内存大小相比并不大,您可能希望对其进行一次解析,然后将结果作为列表存储在内存中:

file2_rows = list(file2)
for row in file1:
  print row
  for prow in file2_rows:
    print prow
于 2012-06-26T15:33:45.003 回答