Dictionary Manipulation

I have a dictionary of dictionaries, which is typed with inscriptions or two, looks like this:

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

The operation I want to perform is as follows:

For each key a:

  • If its value (the innermost dictionary, for example {114905: 1.435.., 114908: 0.846.., 114861: 61.490..}) contains keys that are present as keys on the outermost (in this case 114908), replace them with the values k, vfrom the latter and completely delete it.
  • Finally, convert the foreign key into a tuple containing both the source key and the key that was knocked out of the innermost dict.

The desired result will be as follows:

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

I really hope that you have what I am trying to achieve here because it is not even described.

, , , , . , , - .

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, key: value?

, , , , , - dict. 1.0, dict.

+4
4

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 , : ?

>>> 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 , . , .

+1

Python3.x, {}.keys() . dict.

, :

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, update dict, .

; .. , .

+1
# 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]

, , , ?

0

:

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}}
0

Source: https://habr.com/ru/post/1655867/


All Articles