无法从嵌套for循环访问父for循环

问题描述 投票:1回答:3

我试图比较两个字典数组之间的索引值。为了实现这一点,我使用嵌套的for循环。当循环正确迭代时,存在一个问题,即firstDataSetNumber没有在嵌套for循环内迭代(由第二个print语句指示)。第一个print语句显示for循环正在迭代。什么可能导致从嵌套for循环中的第二个firstDataSetNumber打印的值永远不会改变,即使它在第一个print语句中的值显示它确实正在迭代正确?

def processCommandCenterFile(data):
    firstDataSet = data["FirstDataSet"]
    secondDataSet = data["SecondDataSet"]

    # Go through every First Data Set Record
    for firstDataSetRecord in firstDataSet:
        firstDataSetNumber = firstDataSetRecord["KeyOne"].strip()
        matchingSecondDataSetRecord = None

        print(firstDataSetNumber) # Always iterates properly throughout the application

        # Find the Second Data Set record with the KeyTwo number
        for secondDataSetRecord in secondDataSet:
            print(firstDataSetNumber) # Never iterates past the first value
            if secondDataSetRecord["KeyTwo"].strip() == firstDataSetNumber:
                matchingSecondDataSetRecord = secondDataSetRecord

data = {
    "FirstDataSet": CsvToDictionary("first_data_set.csv"),
    "SecondDataSet": CsvToDictionary("second_data_set.csv")
}

processCommandCenterFile(data)

我期望两个print语句的输出都是一样的。但是,当我运行它时,第一个print语句是索引中的每个项目,但是第二个print语句中的数据卡在列表中的第一个项目上。

FirstDataSet和SecondDataSet键存储以下函数的输出,该函数加载CSV并将其转换为字典,其中CSV标题为键。

import csv

def CsvToDictionary(path):
    file = open(path, 'r')
    rawCsvArray = csv.reader(file, delimiter=',', quotechar='|')
    headers = rawCsvArray.next()
    dataDictionary = csv.DictReader(file, fieldnames=headers)

    return dataDictionary

继承人用于制作FirstDataSet的CSV

KeyOne
143739629
143739629
143750196
143750196
143739646
143739646
143739661
143739661
143739718

然后用于制作SecondDataSet的CSV

KeyTwo
143739629
143739629
143750196
143750196
143739646
143739646
143739661
143739661
143739718
python python-2.7 loops scope
3个回答
1
投票

柯克兰回答了这个问题的实际解决方案。这里有一些背景,如果有人在这里结束。

问题是csv.DictReader()生成了DictReader类型的实例,根据the docs,它“像普通读者一样操作”。 这意味着从DictReader读取值会耗尽实例的内容。 在第一轮内环之后,secondDataSet没有任何东西。在未来的迭代中,内部循环没有任何迭代的元素。

这可以通过在print语句中添加标志来验证:

def processCommandCenterFile(data):
    ...
    for firstDataSetRecord in firstDataSet:
        ...
        print("first print:", firstDataSetNumber) 

    for secondDataSetRecord in secondDataSet:
        print("second print:", firstDataSetNumber) 
        ...

processCommandCenterFile(data)

输出:

('first print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('second print:', '143739629')
('first print:', '143739629')
('first print:', '143750196')
('first print:', '143750196')
('first print:', '143739646')
('first print:', '143739646')
('first print:', '143739661')
('first print:', '143739661')
('first print:', '143739718')

正如柯克兰指出的那样,最好的选择是将DictReader转换为一系列的词组,例如:

list(csv.DictReader(file, fieldnames=headers))

(或者只是使用熊猫。)


0
投票

我解决了这个问题(感谢Blckknght),但是将csv.DictReader的输出转换为如下列表:

import csv

def CsvToDictionary(path):
    file = open(path, 'r')
    rawCsvArray = csv.reader(file, delimiter=',', quotechar='|')
    headers = rawCsvArray.next()
    dataDictionary = csv.DictReader(file, fieldnames=headers)

    return list(dataDictionary)

-1
投票

第一个数据集编号看起来在第二个数据集开始之前声明。然后第二组中的每一个都应该查看firstdataset

© www.soinside.com 2019 - 2024. All rights reserved.