字典操作

2024-09-28 22:06:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典,上面写了一两个等级,看起来像这样:

a = {114907: {114905: 1.4351310915,
              114908: 0.84635577943,
              114861: 61.490648372},
     113820: {113826: 8.6999361654,
              113819: 1.1412795216,
              111068: 1.1964946282,
              117066: 1.5595617822,
              113822: 1.1958951003},
     114908: {114906: 1.279878388,
              114907: 0.77568252572,
              114862: 2.5412545474}
     }

我要做的手术如下:

对于每个键:

  • 如果它的值(最里面的字典,例如{114905: 1.435.., 114908: 0.846.., 114861: 61.490..})也包含作为最外层的键的键(在本例中是114908),则将它们替换为后者中的k, v值,并将其完全删除。在
  • 最后,将最外层的键转换为一个元组,该元组既包含原始键,也包含从最内层dict弹出的键

期望的输出是:

^{pr2}$

我真的希望你能得到我想要的,因为这是无法形容的。在

这是我目前所拥有的,但在几点上都失败了,我深信我走错了路。最终我会到达那里,但这将是有史以来最低效的编码。在

from copy import deepcopy

temp = deepcopy(a)
for item in temp:
    for subitems, values in temp[item].items():
        if values < 1.0:
            for k, v in temp[subitems].items():
                if k != item:
                    a[item][k] = v
#                   a[item].pop(subitems)
for i in a:
    print(i, a[i])
#114908 {114905: 1.4351310915, 114906: 1.279878388, 114907: 0.77568252572, 114861: 61.490648372, 114862: 2.5412545474}
#114907 {114905: 1.4351310915, 114906: 1.279878388, 114908: 0.84635577943, 114861: 61.490648372, 114862: 2.5412545474}
#113820 {113826: 8.6999361654, 113819: 1.1412795216, 111068: 1.1964946282, 117066: 1.5595617822, 113822: 1.1958951003}

附带的问题是,为什么字典中的pop只返回value,而不返回{}对?在

编辑

一个重要的细节可能会使事情变得更简单,那就是寻找需要修改的内容的另一种方法是内部dict值。如果它们低于1.0,它们的键也必然是外部dict的键。在


Tags: inforif字典itemsitempoptemp
3条回答

在Python3.x中,{}.keys()返回一个视图。您可以在dict视图上使用set操作。在

因此,您的算法有点简化为:

outer=a.keys()
deletions=set()
new_a={} 
for k,di in a.items():
    c=outer & di.keys()
    if c:
        c=c.pop()
        if (c,k) not in deletions:
            deletions.add((k,c))
    else:
        new_a[k]=di

for t in deletions:
    del a[t[0]][t[1]], a[t[1]][t[0]]
    new_a[t]=a[t[0]]
    new_a[t].update(a[t[1]])  
>>> new_a
{113820: {113826: 8.6999361654, 
          113819: 1.1412795216, 
          111068: 1.1964946282, 
          117066: 1.5595617822, 
          113822: 1.1958951003}, 
(114908, 114907): {114905: 1.4351310915, 
                   114906: 1.279878388, 
                   114861: 61.490648372, 
                   114862: 2.5412545474}}

元组中元素的顺序可能会根据迭代的顺序和集合操作的顺序而变化。两者都与dicts无序。由于元素可能会有所不同,用作更新dict的dict也是无序的。在

此函数也只适用于单个交集;即,没有创建的元组有超过2个元素作为键。在

这应该行得通

a = {114907: {114905: 1.4351310915,
              114908: 0.84635577943,
              114861: 61.490648372},
     113820: {113826: 8.6999361654,
              113819: 1.1412795216,
              111068: 1.1964946282,
              117066: 1.5595617822,
              113822: 1.1958951003},
     114908: {114906: 1.279878388,
              114907: 0.77568252572,
              114862: 2.5412545474}
     }

# Lets call the keys leaders and its value is a dict of
# keys ( call them members ) to floats.
# if a member is also a leader, then the two leaders combine.

leaders = set(a.keys())
leaders_to_members = { leader: set(member_dict.keys()) for leader, member_dict in a.items() }
seen_leaders =set()
b = {}
for leader, members in leaders_to_members.items():
    if leader in seen_leaders:
        continue

    members_as_leaders = members.intersection(leaders)
    members_as_leaders.add(leader)

    v = {}
    for member_leader in members_as_leaders:
        v.update(a[member_leader])

    seen_leaders.update(members_as_leaders)

    # if its just one element, you want it as the key directly
    b_key = tuple(members_as_leaders) if len(members_as_leaders) > 1 else members_as_leaders.pop()
    # as per your output, you've removed the key to float value if it is a leader
    b_val = { k: float_val for k, float_val in v.items() if k not in members_as_leaders }
    b[b_key] = b_val

print(b)

输出

^{2}$

The side question: why does pop in dictionaries return the value only and not the key: value pair?

>>> a.pop()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pop expected at least 1 arguments, got 0

>>> help(a.pop)
"""
Help on built-in function pop:

pop(...) method of builtins.dict instance
    D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
    If key is not found, d is returned if given, otherwise KeyError is raised
"""

如您所见,pop需要键,因此它可以弹出值。既然你需要给它钥匙,它就不必把钥匙还给你。在

# for each "primary key"
for primary in a.keys():
    # for each "sub-key"
    for sub_key in a[primary].keys():
        # if the sub-key is also a primary key
        if sub_key in a.keys():
            # assign to the subkey the value of its corresponding primary key
            a[primary][sub_key] = a[sub_key]

这就是你要找的,至少在你问题的第一部分?在

相关问题 更多 >