为什么这个嵌套for循环工作在csv.reader对象上?

时间:2012-08-24 20:18:53

标签: python csv

我无法让脚本工作,我怀疑有一些简单的东西我会忽略。我在下面粘贴了一个简化的脚本,为类似的数据集生成相同类型的错误。

下面的脚本用于获取csv,其中每行代表给定状态的轮询数据。使用状态列表,我想迭代csv数据以查找每个州的最新民意调查,并生成列表,列出该州的一个属性(本例中民主党候选人的投票百分比) )。我需要考虑csv文件中的“行”可能没有任何特定顺序,并且某些“状态”可能没有csv中的数据。

此示例脚本为第一个状态(“Alabama”)生成正确的输出,但无法在状态列表中查找任何其他状态的数据。为什么呢?

注1 - 脚本会获取csv文件 注2 - 如果我不是提取csv文件,而是将轮询数据作为列表列表提供

,则脚本按预期工作

感谢您的帮助。

import csv, httplib2, cStringIO

h = httplib2.Http('.cache')
url = 'http://www.electoral-vote.com/evp2012/Pres/pres_polls.csv'
headers, data = h.request(url)

states = [
            "Alabama", 
            "Alaska", 
            "Arizona", 
            "Arkansas", 
            "California", 
            "Colorado", 
            "Connecticut",
            "Delaware",
            "Florida",
            "Georgia",
            "Hawaii",
            "Idaho",
            "Illinois",
            "Indiana",
            "Iowa",
            "Kansas",
            "Kentucky",
            "Louisiana",
            "Maine",
            "Maryland",
            "Massachusetts",
            "Michigan",
            "Minnesota",
            "Mississippi",
            "Missouri",
            "Montana",
            "Nebraska",
            "Nevada",
            "New Hampshire",
            "New Jersey",
            "New Mexico",
            "New York",
            "North Carolina",
            "North Dakota",
            "Ohio",
            "Oklahoma",
            "Oregon",
            "Pennsylvania",
            "Rhode Island",
            "South Carolina",
            "South Dakota",
            "Tennessee",
            "Texas",
            "Utah",
            "Vermont",
            "Virginia",
            "Washington",
            "West Virginia",
            "Wisconsin",
            "Wyoming"
            ]

csv_input = cStringIO.StringIO(data)
csv_output = csv.reader(csv_input)

# sample row => 
#['Day', 'Len', 'State', 'EV', 'Dem', 'GOP', 'Ind', 'Date', '', '', '', '', '', '', '', 'Pollster']
#['  1.0', '1', 'Wyoming', '3', '33', '65', '', 'Jan 01', '', '', '', '', '', '', '', 'Election 2008-1'] 

percent_dem_by_state = []

for state in states:
    poll_day = 0
    percent_dem_for_this_state = [state, None]
    for row in csv_output:
        if (state == row[2]) and (float(row[0]) > poll_day):
            percent_dem_for_this_state = [state, int(row[4])]
            poll_day = float(row[0])
    percent_dem_by_state.append(percent_dem_for_this_state)

for elem in percent_dem_by_state:
    print elem

1 个答案:

答案 0 :(得分:1)

您的循环读取CSV文件“使用它”。每次通过外循环都不会重置。

无论如何,更好的策略是在执行任何其他操作之前读取CSV文件一次,将数据加载到内存中并循环显示。您当前的打算逻辑读取每个状态的整个CSV文件,每次只挑选一个状态的数据,将会比它必须慢一些(大约50倍)慢)。

对于内存中的数据结构,您已经看到列表列表有效。你可以通过字典更好地服务,其中键是状态。然后你不必为每个州循环整个事情。