Python 字典操作
我有一本字典,上面的字典调低了一两个刻度,如下所示:Python 字典操作,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我有一本字典,上面的字典调低了一两个刻度,如下所示: a = {114907: {114905: 1.4351310915, 114908: 0.84635577943, 114861: 61.490648372}, 113820: {113826: 8.6999361654, 113819: 1.1412795216, 111068: 1.1964946282,
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}
}
我要执行的操作如下:
对于a的每个键:
- 如果其值(最里面的字典,例如,
)也包含作为最外面字典上的键出现的键(在本例中为{114905:1.435..114908:0.846..114861:61.490..}
),则将其替换为后面的114908
值,并将其完全删除k,v
- 最后,将最外层的键转换为包含原始键和从最内层dict弹出的键的元组
b = {(114907, 114908): {114905: 1.4351310915,
114906: 1.279878388,
114862: 2.5412545474,
114861: 61.490648372},
113820: {113826: 8.6999361654,
113819: 1.1412795216,
111068: 1.1964946282,
117066: 1.5595617822,
113822: 1.1958951003}
}
我真的希望你能得到我在这里想要达到的,因为这是无法描述的
这就是我到目前为止所做的,但它在几点上都失败了,我深信我走错了路。最终我会到达那里,但这将是有史以来最低效的事情
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}
从复制导入deepcopy
温度=深度复制(a)
对于temp中的项目:
对于子项,临时[item].items()中的值为:
如果值<1.0:
对于临时[subitems].items()中的k,v:
如果k!=项目:
a[项目][k]=v
#a[项目].pop(子项目)
对于我来说,在一个:
打印(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
只返回值
,而不返回键:值
对
编辑
一个可能使事情变得更容易的重要细节是,寻找必须修改的内容的另一种方法是内部dict值。如果它们低于1.0,则它们的键也将绑定为外部dict的键
# 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]
这就是你想要的,至少是你问题的第一部分吗?这应该行得通
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)
输出
{113820: {111068: 1.1964946282,
113819: 1.1412795216,
113822: 1.1958951003,
113826: 8.6999361654,
117066: 1.5595617822},
(114907, 114908): {114861: 61.490648372,
114862: 2.5412545474,
114905: 1.4351310915,
114906: 1.279878388}}
附带问题:为什么pop-in字典只返回值而不返回key:value对
>a.pop()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:pop至少需要1个参数,但得到0个
>>>帮助(流行音乐)
"""
关于内置函数pop的帮助:
builtins.dict实例的pop(…)方法
D.pop(k[,D])->v,删除指定的键并返回相应的值。
如果找不到键,则返回d(如果给定),否则将引发KeyError
"""
如您所见,pop需要键,因此它可以弹出值。既然你需要给它钥匙,它就不必把钥匙还给你。这个怎么样:
import itertools
b ={}
for k1,v1 in a.items():
for k2,v2 in v1.items():
if k2 in a:
a[k2].pop(k1)
a[k1].pop(k2)
dest = dict(itertools.chain(a[k1].items(), a[k2].items())) #python 2.7
b[(k1,k2)] = dest
print b
答复:
{(114908, 114907): {114905: 1.4351310915, 114906: 1.279878388, 114861: 61.490648372, 114862: 2.5412545474}}
在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}}
元组中元素的顺序可能根据迭代顺序和集合操作的顺序而有所不同。两者都是无序的。由于元素可能不同,用作更新dict的dict也是无序的
此功能也仅适用于单个交叉口;i、 例如,不存在使用超过2个元素作为键创建的元组 如果两个外键都包含在各自的值中?听起来这是一个很好的说法@moseskoledoye如果114908的第一个内键是114905而不是114906,你会怎么想?组合的内部dict将具有重复的键。或者这保证是不可能的?@Ev.Kounis我已经更新了关于主要问题的答案。至于附带问题,弹出式词典将键作为参数,因此您无论如何都会知道键。在这种情况下,它只需要弹出值。元组中的顺序重要吗?由于密钥迭代顺序无法保证,因此在运行之间生成的密钥可能会有所不同。只需运行它并将您的输出与所需的输出进行比较。这与我正在做的相似,只是你没有压平内部字典。
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}}