【问题标题】:Using the first row of a CSV as the keys in nested dictionaries?使用 CSV 的第一行作为嵌套字典中的键?
【发布时间】:2021-07-18 02:30:39
【问题描述】:

请不要残忍!我是编码新手,已经在网上寻找答案。我有一个 CSV,其中第一列列出姓名,第二列列出工作,第三列列出出生月份。我想要我在代码下方键入的输出。我制作了字典,但格式如下: {"Karen Fisher": ("IT","November"), etc.} 我希望嵌套字典的键来自 csv 的标题,这样人们知道他们正在查看的关于每个人的数据类型。我收到此错误:“TypeError:'tuple' 对象不支持项目分配”

with open("Example1.csv", "r") as csvfile:
    csvreader = csv.reader(csvfile, delimiter=',')
    row1  = next(csvreader)
    #print(row1)

    def makeadictionary(csvreader):
        dct = {}
        keys = []
        valuesdict = {}
        names = []
        next(csvreader)
        for row in csvreader:
            keys.append(row[0])
            dct[row[0]] = row[1],row[2]
            names.append(row[0])
        #print(names)
        for key,value in dct.items():
            value = list(value)
            #print(value)
            job = value[0]
            #print(job)
            birthmonth = value[1]  
            #print(birthmonth)
            dct[key][row1[1]] = job
            dct[key][row1[2]] = birthmonth
        return dct
    print(makeadictionary(csvreader))

目标输出:{"Karen Fisher":{"job": "IT", "birth month": "November"} 等}

【问题讨论】:

    标签: python list csv dictionary tuples


    【解决方案1】:

    查看代码中的以下行:

    dct[row[0]] = row[1],row[2]
    

    这将创建一个如下形式的字典:

    {"Karen Fisher": ("IT", "November")}
    

    请注意,“Karen Fisher”映射到大小为 2 的元组,也就是说,如果您访问 dct["Karen Fisher"],则会得到元组 ("IT", "November")。现在查看导致错误的行:

    dct[key][row1[1]] = job
    

    我们知道dct[key]等于("IT", "November")row1[1]等于"job",所以python试图执行的是下面的表达式:

    ("IT", "November")["job"] = job
    

    所以它的结构是a[b] = c,其中a 是一个元组。这不起作用有几个原因,其中一个原因是您无法为元组执行该表单的索引分配(元组只能创建,但不能修改),另一个是您无法索引带有字符串的元组。

    您似乎想要在字典中分配一个项目,但您手头没有字典:dct 是字典,但 dct[key] 是元组。你可以做的是创建一个字典:

    dct[key] = {row1[1]: job, row1[2]: birthmonth]}
    

    这应该可行,但还有另一个小问题。在迭代字典时修改字典通常不是一个好习惯。您也不需要对所有内容进行两次迭代。而且我认为您有一个错误,您在标题之后跳过第一行数据(在makeadictionary 中的next(csvreader) 调用中)。最后,您不需要为要完成的任务创建嵌套函数。

    我建议如下:

     with open("Example1.csv", "r") as csvfile:
        csvreader = csv.reader(csvfile, delimiter=',')
        header_row  = next(csvreader)
        result = {}
        for row in csvreader:
          name = row[0]
          result[name] = {}
          for field_name, value in zip(header_row[1:], row[1:]):
            # The zip function 'mixes' the two lists:
            # zip([a, b, c], [d, e, f]) == [(a, d), (b, e), (c, f)]
            result[name][field_name] = value
      print(result)
    
    

    【讨论】:

    • 非常感谢!
    【解决方案2】:

    csv.DictReader 类将返回一个字典。您所要做的就是按键存储条目:

    from pprint import pprint
    import csv
    
    f = open('x.csv','r')
    
    track = {}
    for row in csv.DictReader(f):
        track[row['name']] = dict(row)
    
    pprint( track )
    

    输出:

    {'Joe Blow': {'birth month': 'April', 'job': 'HR', 'name': 'Joe Blow'},
     'Karen Fisher': {'birth month': 'November',
                      'job': 'IT',
                      'name': 'Karen Fisher'}}
    

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 2019-04-09
    • 2016-11-14
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    相关资源
    最近更新 更多