在Python中从csv文件创建嵌套字典

时间:2017-06-28 15:34:02

标签: python

我正在从CSV文件中读取信息,而我正在使用嵌套字典来映射文件中的重复信息。如何为该文件的所有行创建嵌套字典?数据的一个例子(不是实际数据,但基本相同的概念)

State ,City/Region ,Questions ,Answers 
NY,Manhattan ,East/West Coast? ,East 
NY,Manhattan ,been there? ,yes
NY,Brooklyn ,East/West Coast? ,East 
NY,Brooklyn ,been there? ,yes
NY,Brooklyn ,Been to coney island? ,yes
NY,Queens ,East/West Coast? ,East 
NY,Queens ,been there? ,yes
NY ,Staten Island ,is island? ,yes
MA,Boston ,East/West Coast? ,East 
MA,Boston ,like it there? ,yes
MA,Pioneer Valley ,East/West Coast? ,East 
MA,Pioneer Valley ,city? ,no
MA,Pioneer Valley ,college town? ,yes
CA,Bay Area ,warm? ,yes
CA ,Bay Area ,East/West Coast? ,West 
CA ,SoCal ,north or south? ,south 
CA ,SoCal ,warm ,yes 

基本上,主词典有3个键:NY,MA,CA,每个键都有一个以城市/地区为键的字典,每个城市/地区都有问题和答案。
所以它将是一个非常嵌套的字典,但我无法弄清楚它的语法是为文件中的每一行做的。

我尝试打开文件,使用for循环读取行并用“,”分隔行。像这样:

for line in my_file:
    line=line.split(",") 
    MasterDict[line[0]] = {line[1] : {} }
    MasterDict[line[0]][line[1]] = {line[2] : line[3]}

3 个答案:

答案 0 :(得分:0)

import csv
from collections import defaultdict
from functools import partial

defaultdict_of_dict = partial(defaultdict, dict)
master = defaultdict(defaultdict_of_dict)

with open("data.txt", 'r') as f:
    csv_reader = csv.reader(f)
    next(csv_reader)  # Skip the first line
    for row in csv_reader:
        state, city, question, answer = [field.strip() for field in row]
        master[state][city][question] = answer


print(master['NY']['Queens'])
# {'been there?': 'yes', 'East/West Coast?': 'East'}
print(master['NY']['Queens']['been there?'])
# yes

您可以使用csv模块阅读CSV文件,该模块将负责拆分。

您提供的示例数据充满了不必要的空格。如果您的实际数据相同,我们会使用strip进行清理。

为避免在字典中创建缺少的密钥,您可以使用defaultdict。它使用默认值即时创建缺少的键。

例如,你可以这样做:

from collections import defaultdict
d = defaultdict(dict)

使用空dicts创建defaultdict作为缺失键的默认值,并像这样使用它:

d["new_key"]["subkey"] = 5
print(d)
# defaultdict(<class 'dict'>, {'new_key': {'subkey': 5}})

你的情况有一个难点:你想要一个嵌套字典,所以我们需要defaultdict defaultdict dict

我们为defaultdict提供的参数必须是可调用的,因此我们不能编写类似defaultdict(defaultdict(dict))的内容,因为defaultdict(dict)defaultdict,而不是函数。实现此目的的一种方法是使用functools.partial创建defaultdict_of_dict函数,我们可以将其传递给主defaultdict

答案 1 :(得分:0)

我想出了如何让它发挥作用。

import pprint 
MasterDict={}
    my_file.readline()
    for line in my_file:
        line=line.split(",")
        if line[0] not in MasterDict:
            MasterDict[line[0]] = {}
        if line[1]:
            if line[1] not in MasterDict[line[0]]:
                MasterDict[line[0]][line[1]] = []
            MasterDict[line[0]][line[1]].append((line[2], line[3]))
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(MasterDict)

答案 2 :(得分:0)

你可以试试这个稍短的版本:

f = open(myfile).readlines()

f = [i.strip('\n').split(',') for i in f]

d = {i[0]:{i[1]:[]} for i in f[1:]}

for i in f[1:]:
    if i[1] not in d[i[0]]:
        d[i[0]][i[1]] = i[2:]
    else:
        d[i[0]][i[1]].extend(i[2:])

print d