kunal dubey
kunal dubey

Reputation: 77

Nested Dictonary is not updating as required

I'm trying to create a nested dictionary which has sub-dictionary keys as the remaining elements of the list. To explain it in a simpler way:

Required output:

payable = { 'A':{'B':0,'C':0},'B':{'A':0,'C':0}....}

Output:

payable = { 'A':{'B':0,'C':0,'A':0},'B':{'A':0,'C':0,'B':0}....}

I don't need the 'A' sub-key under the 'A' main-key. How can I fix this?

names = ['A', 'B', 'C']  
payable = dict.fromkeys(names, {})  
for mainKey in payable.keys():
    for subKey in names:
        if(mainKey != subKey):
            payable[mainKey][subKey] = 0 
print(payable) 

Upvotes: 2

Views: 77

Answers (3)

RoadRunner
RoadRunner

Reputation: 26315

A simple dict comprehension like this would also work:

>>> names = ['A', 'B', 'C']
>>> {x: dict.fromkeys(names[:i] + names[i+1:], 0) for i, x in enumerate(names)}
{'A': {'B': 0, 'C': 0}, 'B': {'A': 0, 'C': 0}, 'C': {'A': 0, 'B': 0}}

Explanation:

  • Get every other element with list slicing: names[:i] + names[i+1:]
  • initialize dictionary values to zero with dict.fromkeys
  • Use enumerate to iterate over the index and item of names

Additionally, we can use set difference if we don't care about key order, as VPfb shows in the comments:

>>> names = {'A', 'B', 'C'}
>>> {x: dict.fromkeys(names - {x} , 0) for x in names}
{'B': {'C': 0, 'A': 0}, 'C': {'B': 0, 'A': 0}, 'A': {'B': 0, 'C': 0}}

Upvotes: 2

user101
user101

Reputation: 506

Here is a workaround

names = ['A','B','C'] 
payable = dict()
for key in names:
    tmp = dict()
    for sub in names:
        if sub == key:
          tmp[sub] = 0
    payable[key] = tmp
print(payable)
# {'A': {'A': 0}, 'B': {'B': 0}, 'C': {'C': 0}}

Upvotes: 0

Chris
Chris

Reputation: 29742

When you create using dict.fromkeys, all the keys are looking at the same dict.

Try creating payable with dict comprehension (in other words, new dict for each key) and it works fine:

names = ['A','B','C']  
payable= {k:{} for k in names}
for mainKey in payable.keys():
    for subKey in names:
        if(mainKey!=subKey):
            payable[mainKey][subKey]=0 
print(payable) 

Output:

{'A': {'B': 0, 'C': 0}, 'B': {'A': 0, 'C': 0}, 'C': {'A': 0, 'B': 0}}

Upvotes: 5

Related Questions