For converting t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
to dict, I want the output to be {'a':5,'b':2,'c':3}
instead of {'a':4,'b':2,'c':3}
. Is there a way to add up the value of the same key item?
I am using this line to convert the tuple:
dict((x,y) for x, y in t)
My approach: use get with default value 0
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
d = dict()
for x,y in t:
d[x] = d.get(x, 0) + y;
print(d)
Use itertools.groupby
:
from itertools import groupby
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
f = lambda x: x[0]
print({k: sum(x[1] for x in g) for k, g in groupby(sorted(t, key=f), key=f)})
# {'a': 5, 'b': 2, 'c': 3}
Or collections.defaultdict
:
from collections import defaultdict
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
d = defaultdict(int)
for x in t:
d[x[0]] += x[1]
print(d)
# {'a': 5, 'b': 2, 'c': 3}
from collections import Counter
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
h = Counter()
for k, v in t:
h[k] += v
h
Counter({'a': 5, 'c': 3, 'b': 2})
You can write a function that checks whether the key is already present in the dictionary or not. Something like this would work:
d = dict()
for x, y in t:
if x in d:
d[x]+=y
else:
d[x] = y
And that would give you the proper output:
{'a': 5, 'b': 2, 'c': 3}
This is almost verbatim the example from the collections.defaultdict
from collections import defaultdict
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
char_to_int = defaultdict(int)
for k, v in t:
char_to_int[k] += v
Verified in the interpreter
In [1]: from collections import defaultdict
...:
...: t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
...: char_to_int = defaultdict(int)
...:
...: for k, v in t:
...: char_to_int[k] += v
...:
In [2]: char_to_int
Out[2]: defaultdict(int, {'a': 5, 'b': 2, 'c': 3})
Here is the fastest method:
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
out = {}
for x, y in t:
if x in out:out[x] += y
else:out[x] = y
Output:
{'a': 5, 'b': 2, 'c': 3}
This is the simplest method:
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
d = dict.fromkeys(dict(t), 0)
for x, y in t: d[x] += y
Output:
{'a': 5, 'b': 2, 'c': 3}
I used timeit
to calculate that how much time does it take by each method answered by users. The fastest was mine ( Method #1 ):
from timeit import timeit
from itertools import groupby #for method 1
from collections import defaultdict #for method 2 and 5
from collections import Counter #for method 3
t = [('a', 1), ('b', 2), ('c', 3), ('a', 4)]
###############################
######### METHODS ###########
###############################
def method1(): #By Austin
f = lambda x: x[0]
{k: sum(x[1] for x in g) for k, g in groupby(sorted(t, key=f), key=f)}
###############################
def method2(): #By Austin
d = defaultdict(int)
for x in t:
d[x[0]] += x[1]
###############################
def method3(): #By Jean-Claude Arbaut
h = Counter()
for k, v in t:
h[k] += v
###############################
def method4(): #By PHP
d = dict()
for x,y in t:
d[x] = d.get(x, 0) + y;
###############################
def method5(): #By Skam
char_to_int = defaultdict(int)
for k, v in t:
char_to_int[k] += v
###############################
def method6(): #By Aquiles Carattino
d = dict()
for x, y in t:
if x in d:
d[x]+=y
else:
d[x] = y
###############################
def method7(): #My method 2
d = dict.fromkeys(dict(t), 0)
for x, y in t: d[x] += y
###############################
def method8(): #My method 1
out = {}
for x, y in t:
if x in out:out[x] += y
else:out[x] = y
print(timeit(method1))
print(timeit(method2))
print(timeit(method3))
print(timeit(method4))
print(timeit(method5))
print(timeit(method6))
print(timeit(method7))
print(timeit(method8))
The output on my platform was:
5.7539954 1.7488919999999997 4.2322991000000005 1.0104673999999996 1.3571206 0.8095216999999995 1.5506056999999984 0.6387891000000003
So the fastest method is method 8 which I answered ( Method #1 ).
Try:
>>> t = ((1, 'a'),(2, 'b')) >>> dict((y, x) for x, y in t) {'a': 1, 'b': 2}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.