如何在Python中创建嵌套dict?

如何在Python中创建嵌套dict?,python,python-2.7,dictionary,mapping,nested,Python,Python 2.7,Dictionary,Mapping,Nested,我有两个CSV文件:“数据”和“映射”: “映射”文件有4列:Device\u Name,GDN,Device\u Type,和Device\u OS。所有四列都已填充 “数据”文件具有相同的列,填充了Device\u Name列,其他三列为空 我想让我的Python代码打开这两个文件,并为数据文件中的每个Device\u Name,从映射文件映射其GDN、Device\u Type和Device\u OS值 我知道当只存在2列(需要映射1列)时如何使用dict,但当需要映射3列时,我不知道

我有两个CSV文件:“数据”和“映射”:

  • “映射”文件有4列:
    Device\u Name
    GDN
    Device\u Type
    ,和
    Device\u OS
    。所有四列都已填充

  • “数据”文件具有相同的列,填充了
    Device\u Name
    列,其他三列为空
  • 我想让我的Python代码打开这两个文件,并为数据文件中的每个
    Device\u Name
    ,从映射文件映射其
    GDN
    Device\u Type
    Device\u OS
我知道当只存在2列(需要映射1列)时如何使用dict,但当需要映射3列时,我不知道如何实现这一点

以下是我试图使用的代码来完成
设备类型的映射

x = dict([])
with open("Pricing Mapping_2013-04-22.csv", "rb") as in_file1:
    file_map = csv.reader(in_file1, delimiter=',')
    for row in file_map:
       typemap = [row[0],row[2]]
       x.append(typemap)

with open("Pricing_Updated_Cleaned.csv", "rb") as in_file2, open("Data Scraper_GDN.csv", "wb") as out_file:
    writer = csv.writer(out_file, delimiter=',')
    for row in csv.reader(in_file2, delimiter=','):
         try:
              row[27] = x[row[11]]
         except KeyError:
              row[27] = ""
         writer.writerow(row)
它返回
属性错误


经过一些研究,我认为我需要创建一个嵌套的dict,但我不知道如何做到这一点

嵌套dict是字典中的字典。一件很简单的事情

>>> d = {}
>>> d['dict1'] = {}
>>> d['dict1']['innerkey'] = 'value'
>>> d
{'dict1': {'innerkey': 'value'}}
您还可以使用包中的来帮助创建嵌套字典

>>> import collections
>>> d = collections.defaultdict(dict)
>>> d['dict1']['innerkey'] = 'value'
>>> d  # currently a defaultdict type
defaultdict(<type 'dict'>, {'dict1': {'innerkey': 'value'}})
>>> dict(d)  # but is exactly like a normal dictionary.
{'dict1': {'innerkey': 'value'}}

根据你的意见:


可能是上面的代码混淆了问题。简而言之,我的问题是:我 有2个文件a.csv b.csv,a.csv有4列i j k l,b.csv也有 这些栏目。我是这些CSV的关键栏目。j k l柱 在a.csv中为空,但在b.csv中填充。我想映射jk的值 从b.csv文件到a.csv文件中使用“i”作为键列的l列

我的建议如下(不使用defaultdict):


但是请注意,对于解析csv文件,有一个。

更新:对于嵌套字典的任意长度,请转到

使用集合中的defaultdict函数

高性能:当数据集较大时,“if key not in dict”非常昂贵

低维护:使代码更具可读性,并且易于扩展

from collections import defaultdict

target_dict = defaultdict(dict)
target_dict[key1][key2] = val

对于任意嵌套级别:

In [2]: def nested_dict():
   ...:     return collections.defaultdict(nested_dict)
   ...:

In [3]: a = nested_dict()

In [4]: a
Out[4]: defaultdict(<function __main__.nested_dict>, {})

In [5]: a['a']['b']['c'] = 1

In [6]: a
Out[6]:
defaultdict(<function __main__.nested_dict>,
            {'a': defaultdict(<function __main__.nested_dict>,
                         {'b': defaultdict(<function __main__.nested_dict>,
                                      {'c': 1})})})
[2]中的
:def nested_dict():
…:返回集合.defaultdict(嵌套的dict)
...:
在[3]中:a=nested_dict()
在[4]中:a
Out[4]:defaultdict(,{})
在[5]中:a['a']['b']['c']=1
在[6]中:a
出[6]:
defaultdict(,
{'a':defaultdict(,
{'b':defaultdict(,
{c':1}})

使用defaultdict和类似的嵌套dict模块(如
嵌套dict
)时,请务必记住,查找不存在的密钥可能会无意中在dict中创建一个新的密钥条目,并造成大量破坏。

下面是一个带有
嵌套dict
模块的Python3示例:

import nested_dict as nd
nest = nd.nested_dict()
nest['outer1']['inner1'] = 'v11'
nest['outer1']['inner2'] = 'v12'
print('original nested dict: \n', nest)
try:
    nest['outer1']['wrong_key1']
except KeyError as e:
    print('exception missing key', e)
print('nested dict after lookup with missing key.  no exception raised:\n', nest)

# Instead, convert back to normal dict...
nest_d = nest.to_dict(nest)
try:
    print('converted to normal dict. Trying to lookup Wrong_key2')
    nest_d['outer1']['wrong_key2']
except KeyError as e:
    print('exception missing key', e)
else:
    print(' no exception raised:\n')

# ...or use dict.keys to check if key in nested dict
print('checking with dict.keys')
print(list(nest['outer1'].keys()))
if 'wrong_key3' in list(nest.keys()):

    print('found wrong_key3')
else:
    print(' did not find wrong_key3')
输出为:

original nested dict:   {"outer1": {"inner2": "v12", "inner1": "v11"}}

nested dict after lookup with missing key.  no exception raised:  
{"outer1": {"wrong_key1": {}, "inner2": "v12", "inner1": "v11"}} 

converted to normal dict. 
Trying to lookup Wrong_key2 

exception missing key 'wrong_key2' 

checking with dict.keys 

['wrong_key1', 'inner2', 'inner1']  
did not find wrong_key3

如果要为路径创建一个给定列表(任意长度)的嵌套字典,并对路径末尾可能存在的项执行函数,此方便的小递归函数非常有用:

def确保路径(数据,路径,默认值=None,默认值=lambda x:x):
"""
功能:
-确保嵌套字典中存在路径
要求:
-“数据”:
-类型:dict
-什么:检查路径是否存在的字典
-“路径”:
-类型:可疑交易报告清单
-什么:要检查的路径
可选:
-`default`:
-类型:任何
-内容:要添加到尚不存在的路径的默认项
-默认值:无
-`default_func`:
-类型:功能
-内容:一个输入函数,用于接收当前路径项(或默认值)并对其进行调整
-默认值:`lambda x:x`#返回dict中的值,如果不存在,则返回默认值
"""
如果len(路径)>1:
如果路径[0]不在数据中:
数据[路径[0]]={}
data[path[0]]=确保路径(data=data[path[0]],path=path[1:],default=default,default\u func=default\u func)
其他:
如果路径[0]不在数据中:
数据[路径[0]]=默认值
数据[路径[0]]=默认函数(数据[路径[0]])
返回数据
例如:

data={'a':{'b':1}
确保路径(数据=数据,路径=['a','c',默认值=[1])
打印(数据)#=>{'a':{'b':1,'c':[1]}
确保_path(data=data,path=['a','c'],default=[1],default_func=lambda x:x+[2])
打印(数据)#=>{'a':{'b':1,'c':[1,2]}
这是一个空嵌套列表,网元将从中向空dict追加数据

这意味着在数据目录中创建四个空目录

data_dict = {f'dict{i}':{} for i in range(4)}
for i in range(4):
    upd_dict = {'val' : ls[i][0], 'val1' : ls[i][1],'val2' : ls[i][2],'val3' : ls[i][3]}

    data_dict[f'dict{i}'].update(upd_dict)

print(data_dict)
输出

{'dict0':{'val':'a','val1':'a1','val2':'a2','val3':'a3'}, 'dict1':{'val':'b','val1':'b1','val2':'b2','val3':'b3'},'dict2': {'val':'c','val1':'c1','val2':'c2','val3':'c3'},'dict3':{'val':'d','val1':'d1','val2':'d2','val3':'d3'}

#in jupyter
import sys
!conda install -c conda-forge --yes --prefix {sys.prefix} nested_dict 
import nested_dict as nd
d = nd.nested_dict()
“d”现在可以用来存储嵌套的键值对。

pip install addict
travel_log = {
    "France" : {"cities_visited" : ["paris", "lille", "dijon"], "total_visits" : 10},
    "india" : {"cities_visited" : ["Mumbai", "delhi", "surat",], "total_visits" : 12}
}
来自addict导入目录
mapping=Dict()
映射。a.b.c.d.e=2
打印(映射)#{'a':{'b':{'c':{'d':{'e':2}
参考资料:


  • Device\u Name
    列是这两个文件中的键,在此键上我想将Device\u OS、GDN和Device\u Type值从映射文件映射到数据文件。是否希望能够执行类似于
    row[27]=x[row[11][“Device\u OS”]
    的操作?另请参见:--这不需要嵌套的dict,必要。您可以使用pandas,读取\u csv,制作
    Device\u Name
    索引,然后您可以直接
    join
    索引上的两个数据帧
    Device\u Name
    。可能是上面的代码混淆了问题。简而言之,我的问题是:我有两个文件
    a.csv
    b.csv
    a.csv
    有4列
    I j k l
    b.csv
    也有这些列
    i
    是这些CSV的关键列
    jkl
    列在
    a.csv
    中为空,但在
    b.csv
    中填充。我想映射
    jkl
    列的值,使用'I'作为
    data_dict = {f'dict{i}':{} for i in range(4)}
    for i in range(4):
        upd_dict = {'val' : ls[i][0], 'val1' : ls[i][1],'val2' : ls[i][2],'val3' : ls[i][3]}
    
        data_dict[f'dict{i}'].update(upd_dict)
    
    print(data_dict)
    
    #in jupyter
    import sys
    !conda install -c conda-forge --yes --prefix {sys.prefix} nested_dict 
    import nested_dict as nd
    d = nd.nested_dict()
    
    travel_log = {
        "France" : {"cities_visited" : ["paris", "lille", "dijon"], "total_visits" : 10},
        "india" : {"cities_visited" : ["Mumbai", "delhi", "surat",], "total_visits" : 12}
    }