如何将相同的值分组到同一个键中?[已结束]

How to group the same values into same key? [closed]

提问人:user21308739 提问时间:4/4/2023 最后编辑:Cwtuser21308739 更新时间:4/25/2023 访问量:56

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

8个月前关闭。

我有一个任务来做这些事情,而不导入任何有用的功能,你们能帮我吗? 谢谢!

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'}
]

我怎样才能转换成这个是主键,下一个键是newlistnume1

{
    '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 年和 2002 年只有 k,而 k 只有一个数据,因此它将是 k 的唯一成员 你会看到它的形式{ num: {e1: [ {'num':..., 'e1': ..., 'e2': ... }, ... ], ...}, ... }

python-3.x 字典 嵌套迭代 解包

评论

1赞 motto 4/4/2023
关于这个话题,以前有很多问题,也许它们会有所帮助
0赞 Gameplay 4/4/2023
您没有提供您尝试过的代码,老实说,从我的 POV 来看,描述是完全无法理解的。
0赞 TylerH 4/25/2023
@Gameplay 请注意,添加的代码只是调试问题的要求。这是一个“如何做”的问题,不需要代码。

答:

0赞 Driftr95 4/4/2023 #1

一种方法是遍历输入列表(或)并使用 .setdefault 并填充嵌套的字典或列表。datanewlist.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:]] # <-- 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)

您还可以使用字典推导来创建包含空列表的嵌套字典,然后遍历输入列表中的每个字典,或者将输入列表中的每个字典添加到嵌套字典中它所属的任何列表。datanewlist

(在定义嵌套字典时,可以使用列表推导立即过滤每个嵌套键的输入列表,但在单独的循环中执行此操作实际上会减少遍历输入数据的总次数。


要从 中获取嵌套字典,可以使用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)))

## 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}}
''' 


要从 中获取嵌套字典,可以使用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)

## 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}}
'''

无论采用哪种方法,都应该看起来像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'}]
  }
}