I am making a list word counter and trying to merge two dictionaries that have a counter for each character, but I keep getting the wrong outputs. Here is what I attempted in an effort to figure out why. Everything seems to go well except for the last two keys in the dictionary.
counts = {"a": 1, "p": 2, "l": 1, "e": 1}
new_counts = {"h": 1, "e": 1, "l": 2, "o": 1}
counts.update(new_counts)
for letters in counts:
if letters in counts and new_counts:
counts[letters] = 1
else:
counts[letters] = 1
print(counts)
What I need:
{"a": 1, "p": 2, "l": 3, "e": 2, "h": 1, "o": 1}
What I get:
{'a': 2, 'p': 3, 'l': 3, 'e': 2, 'h': 2, 'o': 2}
CodePudding user response:
If we are in Python structures, actually it is a Counter
that is ideal here.
from collections import Counter
c1 = Counter({"a": 1, "p": 2, "l": 1, "e": 1})
c2 = Counter({"h": 1, "e": 1, "l": 2, "o": 1})
print(c1 c2)
CodePudding user response:
You can use a simple for-loop:
counts = {"a": 1, "p": 2, "l": 1, "e": 1}
new_counts = {"h": 1, "e": 1, "l": 2, "o": 1}
for k, v in new_counts.items():
if k in counts:
counts[k] = v
else:
counts[k] = v
print(counts) # => {'a': 1, 'p': 2, 'l': 3, 'e': 2, 'h': 1, 'o': 1}
This is actually the fastest method. I tested it with timeit
against kosciej16's answer and his took 5.49 seconds, while mine took 0.73 seconds (for one million iterations). I also tested against wim's dictionary comprehension answer and that took 1.95 seconds, while mine took 0.85 seconds.
CodePudding user response:
This would be an ideal place to use collections.defaultdict
. Creating a new defaultdict
, we iterate over both dictionaries' items and add their values to the defaultdict
.
>>> from collections import defaultdict
>>> d = defaultdict(int)
>>> counts = {"a": 1, "p": 2, "l": 1, "e": 1}
>>> new_counts = {"h": 1, "e": 1, "l": 2, "o": 1}
>>> for k, v in counts.items():
... d[k] = v
...
>>> for k, v in new_counts.items():
... d[k] = v
...
>>> d
defaultdict(<class 'int'>, {'a': 1, 'p': 2, 'l': 3, 'e': 2, 'h': 1, 'o': 1})
CodePudding user response:
Using collections.Counter
, a dict subclass designed for this kind of thing, you can just add instances directly using the
operator:
>>> from collections import Counter
>>> counts = {"a": 1, "p": 2, "l": 1, "e": 1}
>>> new_counts = {"h": 1, "e": 1, "l": 2, "o": 1}
>>> Counter(counts) Counter(new_counts)
Counter({'a': 1, 'p': 2, 'l': 3, 'e': 2, 'h': 1, 'o': 1})
Using a dict comprehension:
>>> all_keys = counts.keys() | new_counts.keys()
>>> {k: counts.get(k, 0) new_counts.get(k, 0) for k in all_keys}
{'p': 2, 'h': 1, 'o': 1, 'e': 2, 'l': 3, 'a': 1}