I have the following dictionary, keys being tuples:
defaultdict(<class 'float'>, {('abc', 'xyz'): 1.0, ('abc', 'def'):
3.0, ('abc', 'pqr'): 1.0, ('pqr', 'xyz'): 1.0, ('pqr', 'def'): 1.0})
How do I count up the first key element and second key element, so that I can get:
defaultdict(<class 'float'>, {'abc': 3.0, 'pqr': 3.0})
and
defaultdict(<class 'float'>, {'xyz': 2.0, 'def': 2.0, 'pqr': 1.0})
I am ignoring the values in the original dictionary and just counting up unique keys (first and second separately).
I want to do something like the following, but I get an error "'tuple' object has no attribute 'items'":
first_key_list =[j[0][0] for i in dictionary for j in i.items()]
new_dict = collections.defaultdict(float)
for i in first_key_list:
new_dict[i] += 1
for i in dictionary for j in i.items()
doesn't work because outer loop yields the dictionary keys (the tuples), and items
don't apply to tuples
.
Anyway, it seems that you're ignoring the values of your dictionaries. Just use collections.Counter
on the first part of the key:
d = {('abc', 'xyz'): 1.0, ('abc', 'def'):
3.0, ('abc', 'pqr'): 1.0, ('pqr', 'xyz'): 1.0, ('pqr', 'def'): 1.0}
import collections
d1 = collections.Counter(k[0] for k in d)
print(d1)
result:
Counter({'abc': 3, 'pqr': 2})
if you want floats, I suggest that you convert to float after having counted to avoid floating point inaccuracy:
{k:float(v) for k,v in d1.items()}
or in one line:
d1 = {k:float(v) for k,v in collections.Counter(k[0] for k in d).items()}
to keep keys as tuples:
d1 = {(k,):float(v) for k,v in collections.Counter(k[0] for k in d).items()}
for the second part, just use k[1]
instead.