我有一个数据结构,基本上相当于嵌套字典.让我们说它看起来像这样:
{'new jersey': {'mercer county': {'plumbers': 3,
'programmers': 81},
'middlesex county': {'programmers': 81,
'salesmen': 62}},
'new york': {'queens county': {'plumbers': 9,
'salesmen': 36}}}
Run Code Online (Sandbox Code Playgroud)
现在,保持和创造这个是非常痛苦的; 每当我有一个新的州/县/专业时,我必须通过令人讨厌的try/catch块创建下层词典.而且,如果我想要遍历所有值,我必须创建恼人的嵌套迭代器.
我也可以使用元组作为键,如下:
{('new jersey', 'mercer county', 'plumbers'): 3,
('new jersey', 'mercer county', 'programmers'): 81,
('new jersey', 'middlesex county', 'programmers'): 81,
('new jersey', 'middlesex county', 'salesmen'): 62,
('new york', 'queens county', 'plumbers'): 9,
('new york', 'queens county', 'salesmen'): 36}
Run Code Online (Sandbox Code Playgroud)
这使得迭代值非常简单和自然,但是做聚合和查看字典的子集(例如,如果我只想逐个状态)这样做更具语法上的痛苦.
基本上,有时我想将嵌套字典视为平面字典,有时我想将其视为复杂的层次结构.我可以把它全部包装在一个类中,但似乎有人可能已经完成了这个.或者,似乎可能有一些非常优雅的语法结构来做到这一点.
我怎么能做得更好?
附录:我知道setdefault()但它并没有真正实现干净的语法.此外,您创建的每个子词典仍需要setdefault()手动设置.
我有2个csv文件.第一个是数据文件,另一个是映射文件.映射文件中有4列:Device_Name,GDN,Device_Type,和Device_OS.数据文件中存在相同的列.
数据文件包含Device_Name填充列的数据,其他三列为空.所有四列都填充在Mapping文件中.我希望我的Python代码来打开这两个文件并为每个Device_Name数据文件,它的映射GDN,Device_Type以及Device_OS从映射文件中值.
我知道当只有2列存在时如何使用dict(需要映射1个)但我不知道如何在需要映射3列时完成此操作.
以下是我尝试完成映射的代码Device_Type:
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)
Run Code Online (Sandbox Code Playgroud)
它返回Atribute Error.
经过一番研究,我意识到我需要创建一个嵌套的dict,但我不知道如何做到这一点.请帮我解决这个问题,或者按照正确的方向推动我解决这个问题.
假设有这样的结构:
{'key1' : { 'key2' : { .... { 'keyn' : 'value' } ... } } }
Run Code Online (Sandbox Code Playgroud)
使用python,我试图确定两种不同方法的优点/缺点:
{'key1' : { 'key2' : { .... { 'keyn' : 'value' } ... } } } # A. nested dictionary
{('key1', 'key2', ...., 'keyn') : 'value'} # B. a dictionary with a tuple used like key
Run Code Online (Sandbox Code Playgroud)
然后我有兴趣知道,最好的(A或B)是什么:
是否有一种有效的方法来创建分层JSON(n级深度),其中父值是键而不是变量标签?即:
{"2017-12-31":
{"Junior":
{"Electronics":
{"A":
{"sales": 0.440755
}
},
{"B":
{"sales": -3.230951
}
}
}, ...etc...
}, ...etc...
}, ...etc...
Run Code Online (Sandbox Code Playgroud)
1.我的测试DataFrame:
colIndex=pd.MultiIndex.from_product([['New York','Paris'],
['Electronics','Household'],
['A','B','C'],
['Junior','Senior']],
names=['City','Department','Team','Job Role'])
rowIndex=pd.date_range('25-12-2017',periods=12,freq='D')
df1=pd.DataFrame(np.random.randn(12, 24), index=rowIndex, columns=colIndex)
df1.index.name='Date'
df2=df1.resample('M').sum()
df3=df2.stack(level=0).groupby('Date').sum()
Run Code Online (Sandbox Code Playgroud)
2.我正在进行转换,因为它似乎是构建JSON的最合理的结构:
df4=df3.stack(level=[0,1,2]).reset_index() \
.set_index(['Date','Job Role','Department','Team']) \
.sort_index()
Run Code Online (Sandbox Code Playgroud)
我的尝试 - 迄今为止
我遇到了这个非常有用的SO问题,它使用以下代码解决了一级嵌套的问题:
j =(df.groupby(['ID','Location','Country','Latitude','Longitude'],as_index=False) \
.apply(lambda x: x[['timestamp','tide']].to_dict('r'))\
.reset_index()\
.rename(columns={0:'Tide-Data'})\
.to_json(orient='records'))
Run Code Online (Sandbox Code Playgroud)
...但是我找不到让嵌套.groupby()工作的方法:
j=(df.groupby('date', as_index=True).apply(
lambda x: x.groupby('Job Role', as_index=True).apply(
lambda x: x.groupby('Department', as_index=True).apply(
lambda x: x.groupby('Team', as_index=True).to_dict()))) \
.reset_index().rename(columns={0:'sales'}).to_json(orient='records'))
Run Code Online (Sandbox Code Playgroud) 我试图转换点分隔字符串列表,例如
['one.two.three.four', 'one.six.seven.eight', 'five.nine.ten', 'twelve.zero']
Run Code Online (Sandbox Code Playgroud)
到树(嵌套列表或dicts - 易于穿过的任何东西).实际数据恰好有1到4个不同长度的点分离部分,总共有2200个记录.我的实际目标是用这些数据填充4个QComboBox'的集合,方式是第一个QComboBox填充第一个设置项['one','five','12'](没有重复).然后根据所选项目,第二个QComboBox将填充其相关项:对于'one',它将是:['two','six'],依此类推,如果有另一个嵌套级别.
到目前为止,我有一个工作列表 - >嵌套dicts解决方案,但它非常慢,因为我使用常规dict().我似乎很难将其重新设计为defaultdict,以便轻松地正确填充ComboBox.
我目前的代码:
def list2tree(m):
tmp = {}
for i in range(len(m)):
if m.count('.') == 0:
return m
a = m.split('.', 1)
try:
tmp[a[0]].append(list2tree(a[1]))
except (KeyError, AttributeError):
tmp[a[0]] = list2tree(a[1])
return tmp
main_dict = {}
i = 0
for m in methods:
main_dict = list2tree(m)
i += 1
if (i % 100) == 0: print i, len(methods)
print main_dict, i, len(methods)
Run Code Online (Sandbox Code Playgroud) 假设我有一个键列表
key_lst = ["key1", "key2", "key3"]
Run Code Online (Sandbox Code Playgroud)
我有一个价值
value = "my_value"
Run Code Online (Sandbox Code Playgroud)
以及my_dict具有此结构的示例dict
{
"key1": {
"key2": {
"key3": "some_value"
}
},
}
Run Code Online (Sandbox Code Playgroud)
如何通过遍历/循环value来动态地将变量中的新值分配给?my_dict["key1"]["key2"]["key3"]key_lst
我不能只说my_dict["key1"]["key2"]["key3"] = value因为钥匙和钥匙的数量正在改变.我总是在列表中获取密钥(我必须保存值的路径)...
我正在使用Python 3.7
我有四件事要使用push_to_dict方法推送到 dict user_post_dict
user_post_dict= {}
def push_to_dict(user_email, post_id, question_text, question_answer):
if user_email in user_post_dict:
if post_id in user_post_dict[user_email]:
user_post_dict[user_email][post_id][question_text] = question_answer
else:
user_post_dict[user_email][post_id] = {}
user_post_dict[user_email][post_id][question_text] = question_answer
else:
user_post_dict[user_email] = {}
user_post_dict[user_email][post_id] = {}
user_post_dict[user_email][post_id][question_text] = question_answer
push_to_dict('abc@gmail.com',1,'what is this?', 'this is something')
push_to_dict('abc@gmail.com',2,'what is that?', 'that is something')
push_to_dict('def@gmail.com',1,'what is this?', 'this is something')
push_to_dict('def@gmail.com',2,'what is that?', 'that is something')
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法来优化代码或缩短代码。
python ×7
dictionary ×6
mapping ×2
nested ×2
python-3.x ×2
dataframe ×1
defaultdict ×1
json ×1
list ×1
optimization ×1
pandas ×1
pyside ×1
python-2.7 ×1