I have nested dictionary with user input data:
{
name: {key_to_compare: value, key_to_compare: value},
name: {key_to_compare: value, key_to_compare: value},
name :{key_to_compare: value, key_to_compare: value},
...
Number of name-key as well nested {key_to_compare: value}
might vary. Then as input a get two name_key
The task is to compare the values of the same key_to_compare
under different name-key
and the key_to_compare
with lower value to be removed. At the end the dictionary should keep the same format.
This is what I have tried:
first_player, second_player = split_line
player_to_remove[first_player] = []
player_to_remove[second_player] = []
if first_player in players_data.keys() and second_player in players_data.keys():
for fp_keys, fp_value in players_data[first_player].items():
for sp_keys, sp_value in players_data[second_player].items():
if fp_keys == sp_keys:
if fp_value > sp_value:
player_to_remove[second_player].append(sp_keys)
break
elif fp_value < sp_value:
player_to_remove[first_player].append(fp_keys)
break
elif fp_value == sp_value:
break
if player_to_remove:
for key, value in player_to_remove.items():
for skill, points in players_data[key].items():
if skill in value:
players_data[key].pop(skill)
This is part of the a the code that handle it. I try to loop the name_key
and compare the key_to_compare
values. The problems is that I can't modify the dictionary during the loops.
I tried to collect the key_to_compare
in a separate dict with name as a key and a list of key_to_compare
as values and then comparing to dictionaries to remove the matching key_to_compare
for corresponding key_names
.
I can't figure it out how to do it and may be there is some different approach in the first place.
This example of the dictionary:
{'Peter': {'Adc': 400}, 'Bush': {'Tank': 150}, 'Frank': {'Mid': 200, 'Support': 250, 'Tank': 250}}
CodePudding user response:
I will suppose that your dictionnary is in the form that I'm writing here. In that case, the following code should work
dict = { 'alice' : {'key1' : 1, 'key2' : 2},'bob' : {'key2' : 0.1, 'key3' : 5}, 'carol' : {'key4' : 1}}
#Get the list of all keys, using set.union
listOfKeys = set.union(*[ set(dict[d].keys()) for d in dict ])
print(listOfKeys)
#{'key1', 'key2', 'key3', 'key4'}
#Get, for each key, a dict of every name who has the key
for k in listOfKeys :
namesWithKey = { name : dict[name][k] for name in dict for nameKey in dict[name] if k in nameKey}
print(k,namesWithKey)
# key3 {'bob': 'key3'}
# key1 {'alice': 'key1'}
# key2 {'alice': 'key2', 'bob': 'key2'}
# key4 {'carol': 'key4'}
#Remove the smallest one
if len(namesWithKey) > 1 :
minName = min(namesWithKey,key=namesWithKey.get)
del dict[minName][k]
print(dict)
# {'alice': {'key1': 1, 'key2': 2}, 'bob': {'key3': 5}, 'carol': {'key4': 1}}
Here, we have an arbitrary number of keys and names, and only the intersection get removed, see key 2 that both Alice and Bob have.
Is that the question ?
CodePudding user response:
EDIT:
dct = {
"Peter": {"Adc": 400},
"Bush": {"Tank": 150},
"Frank": {"Mid": 200, "Support": 250, "Tank": 250},
}
def compare(dct, key1, key2):
item1 = dct.pop(key1) if key1 in dct else {}
item2 = dct.pop(key2) if key2 in dct else {}
for k in item1.keys() & item2.keys():
if item1[k] > item2[k]:
item2.pop(k)
elif item1[k] < item2[k]:
item1.pop(k)
if item1:
dct[key1] = item1
if item2:
dct[key2] = item2
compare(dct, "Bush", "Frank")
print(dct)
Prints:
{"Peter": {"Adc": 400}, "Frank": {"Mid": 200, "Support": 250, "Tank": 250}}