问题
a while ago i asked a question about comparing 2 dicts to eachother, in order to detect same key's and keep the highest value of duplicates. this community came with the a soltion which allowed me to compare 2 dicts to eachother and store the highest value of it in a new dict, which i can then compare to another dict if neccesary.
but as the number of dicts are getting higher, the code itself keeps getting larger.
for key in dict1:
if key not in dict2 or dict1[key] > dict2[key]:
dict2[key] = dict1[key]
dict2a = {**dict1, **dict2}
for key in dict2a:
if key not in dict3 or dict2a[key] > dict3[key]:
dict3[key] = dict2a[key]
dict3a = {**dict2a, **dict3}
for key in dict3a:
if key not in dict4 or dict3a[key] > dict4[key]:
dict4[key] = dict3a[key]
dict4a = {**dict3a, **dict4}
Im trying to come up with a solution that will iterate over all these dicts. This question also hangs together with another question, but to keep solutions seperated, i ask this question in another help-question (how to open up multiple json txt files without getting errors and stops). Trying to get shorter way of opening multiple txt files
In short, atm im creating a dict for each played contest, with playernames as key's and their scores a values. This dict comparison is needed to filter playernames who attended to more then 1 contest, and to keep only their highest score. But perhaps another solution to this is to store all those different dicts in 1 big nested dict. That is at least the hint my teacher gave me. But i cannot find a way to compare nested dicts to eachother, and thus atm im bound to all these seperated dicts.
If any info is unclear please let me know so i can try to clearify it more.
thnx in advance
update: an example of what is reached after a comparison:
dict1 = {"name1": 100, "name2": 20, "name4": 111}
dict2 = {"name4": 112, "name5": 23}
compared_dict = {"name1": 100, "name2": 20, "name4": 112, "name5": 23}
回答1:
So the two rules are:
- Filter out duplicates
- Include the score of the newest dictionary if it is greater than the old one
You are copying a lot of code... one of the first rules of coding best practices is DRY (don't repeat yourself!)
Let's define a method to merge our old and new dictionaries
def merge_dictionaries(old, new):
changes = {}
# keep the old one, don't edit the new one
copy = old.copy()
for player in new.keys():
new_score = new[player]
try:
old_score = old[player]
except KeyError:
# if player doesn't exist in the old set, add them to the changes
changes[player] = new_score
continue
if new_score > old_score:
changes[player] = new_score
copy.update(changes)
return copy
The next step would be to iterate over a list of these dictionaries containing playernames and scores to total to a final result using the method above.
One solution may look like this:
def final_result(list_of_games):
final = {}
for results in list_of_games:
final = merge_dictionaries(final, results)
return final
A working example:
def merge_dictionaries(old, new):
changes = {}
# keep the old one, don't edit the new one
copy = old.copy()
for player in new.keys():
new_score = new[player]
try:
old_score = old[player]
except KeyError:
# if player doesn't exist in the old set, add them to the changes
changes[player] = new_score
continue
if new_score > old_score:
changes[player] = new_score
copy.update(changes)
return copy
def final_result(list_of_games):
final = {}
for results in list_of_games:
final = merge_dictionaries(final, results)
return final
games = [
{'kevin': 1, 'jack': 5},
{'kevin': 2, 'blueberry': 1, 'jack': 3},
{'kevin': 1, 'blueberry': 5, 'jack': 10}
]
print(final_result(games))
Which outputs
{'kevin': 2, 'jack': 10, 'blueberry': 5}
回答2:
The processing you've described doesn't sound like comparing dictionaries is required—it seems like you want to merge them together (and retaining only the highest score obtained by each player).
The combine_dicts()
function below will accept any number of input dictionaries (collectively named args
because of the *
prefix.)
def combine_dicts(*args):
combined = {}
for arg in args:
for player, score in arg.items():
combined[player] = max(combined.get(player, 0), score)
return combined
dict1 = {"name1": 100, "name2": 20, "name4": 111}
dict2 = {"name4": 112, "name5": 23}
result = combine_dicts(dict1, dict2)
print(result)
Output:
{'name1': 100, 'name2': 20, 'name4': 112, 'name5': 23}
来源:https://stackoverflow.com/questions/47877373/searching-for-a-more-elegant-less-code-way-to-compare-multiple-dicts