英文:
How to group the same values into same key?
问题
{
'2001': {
'k': [
{'num': '2001', 'e1': 'k', 'e2': 'r', 'e3': 'e'}
]
},
'2002': {
'k': [
{'num': '2002', 'e1': 'k', 'e2': 'r', 'e3': 'i'}
],
'p': [
{'num': '2002', 'e1': 'p', 'e2': 'r', 'e3': 'i'}
]
},
'2004': {
'p': [
{'num': '2004', 'e1': 'p', 'e2': 'a', 'e3': 'p'},
{'num': '2004', 'e1': 'p', 'e2': 's', 'e3': 'f'}
]
}
}
英文:
I have an assignment to do this things without import any helpful function, could you guys help me?
Thanks!
data = [
['num','e1','e2','e3'],
['2002','p','r','i'],
['2002','k','r','i'],
['2001','k','r','e'],
['2004','p','a','p'],
['2004','p','s','f']
]
newlist = [
{'num': '2001', 'e1': 'k', 'e2': 'r', 'e3': 'e'},
{'num': '2002', 'e1': 'p', 'e2': 'r', 'e3': 'i'},
{'num': '2002', 'e1': 'k', 'e2': 'r', 'e3': 'i'},
{'num': '2004', 'e1': 'p', 'e2': 'a', 'e3': 'p'},
{'num': '2004', 'e1': 'p', 'e2': 's', 'e3': 'f'}
]
How can I convert newlist
into this by num
is main key and next key is e1
{
'2001':{
'k':[{'num': '2001', 'e1': 'k', 'e2': 'r', 'e3': 'e'}]
},
'2002':{
'k':[{'num': '2002', 'e1': 'k', 'e2': 'r', 'e3': 'i'}],
'p':[{'num': '2002', 'e1': 'p', 'e2': 'r', 'e3': 'i'}]
},
'2004':{
'p':[{'num': '2004', 'e1': 'p', 'e2': 'a', 'e3': 'p'}, {'num': '2004', 'e1': 'p', 'e2': 's', 'e3': 'f'}]
}
}
2001 and 2002 have only k and k have only one data so it will be the only one member of k
you will see its form { num: {e1: [ {'num':..., 'e1': ..., 'e2': ... }, ... ], ...}, ... }
答案1
得分: 0
一种方法是遍历输入列表(data
或 newlist
)并使用 .setdefault
和 .append
来填充嵌套的字典或列表。
从 data
中获取嵌套字典:
result, kList, vData = {}, data[0], data[1:]
for r in vData:
k_outer, k_inner = r[:2]
dict_inner = result.setdefault(k_outer, {})
list_inner = dict_inner.setdefault(k_inner, [])
list_inner.append(dict(zip(kList, r)))
从 newlist
中获取嵌套字典:
# newlist = [dict(zip(data[0],r)) for r in data[1:]] # <-- 从 data 获取 newlist
result, k_outer_key, k_inner_key = {}, 'num', 'e1'
for r in newlist:
k_outer, k_inner = r.get(k_outer_key), r.get(k_inner_key)
dict_inner = result.setdefault(k_outer, {})
list_inner = dict_inner.setdefault(k_inner, [])
list_inner.append(r)
你也可以使用字典推导式来创建一个包含空列表的嵌套字典,然后遍历 data
或 newlist
并将输入列表中的每个字典添加到嵌套字典中相应的列表中。
(在定义嵌套字典时,你可以直接使用列表推导式为每个嵌套键筛选输入列表,但在单独的循环中执行此操作实际上会减少你循环遍历输入数据的总次数。)
从 data
中获取嵌套字典,你可以使用:
kList, vData = data[0], data[1:]
result = {k_outer: {
k_inner: [] for k, k_inner, *_ in vData if k==k_outer
} for k_outer in {k1 for k1, *_ in vData}}
for r in vData: result[r[0]][r[1]].append(dict(zip(kList,r)))
## 或者
''' ## [稍微不那么高效]
kList, vData = data[0], data[1:]
result = {k_outer: {
k_inner: [dict(zip(kList,x)) for x in vData if x[0]==k_outer and x[1]==k_inner]
for k, k_inner, *_ in vData if k==k_outer
} for k_outer in {k1 for k1, *_ in vData}}
'''
<br>
从 newlist
中获取嵌套字典,你可以使用:
k_outer, k_inner = 'num', 'e1'
result = {k: {
d.get(k_inner): [] for d in newlist if k==d.get(k_outer)
} for k in {r.get(k_outer) for r in newlist}}
for r in newlist: result[r.get(k_outer)][r.get(k_inner)].append(r)
## 或者
''' ## [稍微不那么高效]
k_outer, k_inner = 'num', 'e1'
result = {k: {d.get(k_inner): [
x for x in newlist if x.get(k_outer)==k and x.get(k_inner)==d.get(k_inner)
] for d in newlist if k==d.get(k_outer)} for k in {r.get(k_outer) for r in newlist}}
'''
无论采用哪种方法,result
应该看起来像:
{
'2004': {
'p': [{'num': '2004', 'e1': 'p', 'e2': 'a', 'e3': 'p'}, {'num': '2004', 'e1': 'p', 'e2': 's', 'e3': 'f'}]
},
'2002': {
'p': [{'num': '2002', 'e1': 'p', 'e2': 'r', 'e3': 'i'}],
'k': [{'num': '2002', 'e1': 'k', 'e2': 'r', 'e3': 'i'}]
},
'2001': {
'k': [{'num': '2001', 'e1': 'k', 'e2': 'r', 'e3': 'e'}]
}
}
英文:
One way would be to loop through the input list (data
or newlist
) and use .setdefault
and .append
to fill up the nested dictionary or lists.
To get the nested dictionary from data
:
result, kList, vData = {}, data[0], data[1:]
for r in vData:
k_outer, k_inner = r[:2]
dict_inner = result.setdefault(k_outer, {})
list_inner = dict_inner.setdefault(k_inner, [])
list_inner.append(dict(zip(kList, r)))
To get the nested dictionary from newlist
:
# newlist = [dict(zip(data[0],r)) for r in data[1:]] # <-- get newlist from data
result, k_outer_key, k_inner_key = {}, 'num', 'e1'
for r in newlist:
k_outer, k_inner = r.get(k_outer_key), r.get(k_inner_key)
dict_inner = result.setdefault(k_outer, {})
list_inner = dict_inner.setdefault(k_inner, [])
list_inner.append(r)
You can also use dictionary comprehension to create a nested dictionary containing empty lists and then loop through data
or newlist
and add each dictionary in the input list to whichever list it belongs to in the nested dictionary.
(You could filter the input list for each nested key right away with list comprehension when you're defining the nested dictionary, but doing it in a separate loop actually reduces the total number of times you loop through the input data.)
To get the nested dictionary from data
, you can use
kList, vData = data[0], data[1:]
result = {k_outer: {
k_inner: [] for k, k_inner, *_ in vData if k==k_outer
} for k_outer in {k1 for k1, *_ in vData}}
for r in vData: result[r[0]][r[1]].append(dict(zip(kList,r)))
## OR
''' ## [SLIGHTLY LESS EFFICIENT]
kList, vData = data[0], data[1:]
result = {k_outer: {
k_inner: [dict(zip(kList,x)) for x in vData if x[0]==k_outer and x[1]==k_inner]
for k, k_inner, *_ in vData if k==k_outer
} for k_outer in {k1 for k1, *_ in vData}}
'''
<br>
To get the nested dictionary from newlist
, you can use
k_outer, k_inner = 'num', 'e1'
result = {k: {
d.get(k_inner): [] for d in newlist if k==d.get(k_outer)
} for k in {r.get(k_outer) for r in newlist}}
for r in newlist: result[r.get(k_outer)][r.get(k_inner)].append(r)
## OR
''' ## [SLIGHTLY LESS EFFICIENT]
k_outer, k_inner = 'num', 'e1'
result = {k: {d.get(k_inner): [
x for x in newlist if x.get(k_outer)==k and x.get(k_inner)==d.get(k_inner)
] for d in newlist if k==d.get(k_outer)} for k in {r.get(k_outer) for r in newlist}}
'''
Whichever approach is taken, result
should look like
> py
> {
> '2004': {
> 'p': [{'num': '2004', 'e1': 'p', 'e2': 'a', 'e3': 'p'}, {'num': '2004', 'e1': 'p', 'e2': 's', 'e3': 'f'}]
> },
> '2002': {
> 'p': [{'num': '2002', 'e1': 'p', 'e2': 'r', 'e3': 'i'}],
> 'k': [{'num': '2002', 'e1': 'k', 'e2': 'r', 'e3': 'i'}]
> },
> '2001': {
> 'k': [{'num': '2001', 'e1': 'k', 'e2': 'r', 'e3': 'e'}]
> }
> }
>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论