I have the following dictionary:
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
I want to add the integer components of all "similar" values for each list.
(Similar means that the strings end with the same character.)
I want the final output to be:
items = {1: ['7a', '3c', '6b'], 2: ['7a', '3c', '6b']}
This would work:
from collections import defaultdict
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'],
2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
for key, value in items.items():
counting = defaultdict(int)
for elem in value:
counting[elem[1]] += int(elem[0])
items[key] = [str(v) + k for k,v in counting.items()]
print(items)
The following works, assuming that there's only one letter at the end of each string. Adjust indices accordingly if your alphanumeric strings are more complicated.
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
def group_alphanum(alnums):
import itertools
alnums = sorted(alnums, key=lambda s: s[-1])
for grp, items in itertools.groupby(alnums, key=lambda s: s[-1]):
al = grp[-1]
num = sum(int(item[:-1]) for item in items)
yield "{}{}".format(num, al)
grouped_items = {k: list(group_alphanum(vals)) for k, vals in items.items()}
# {1: ['7a', '6b', '3c'], 2: ['7a', '6b', '3c']}
With itertools.groupby
function:
import itertools
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
d = {} # new dict
f = lambda x: x[-1] # function to get the last char from each item
for key,l in items.items():
d[key] = [ str(sum(int(n[:-1]) for n in g)) + k
for k,g in itertools.groupby(sorted(l, key=f), key=f) ]
print(d)
The output:
{1: ['7a', '6b', '3c'], 2: ['7a', '6b', '3c']}
here's one way to do it: ( d
is your original dictionary)
from itertools import groupby
# iterate through the k,value pairs of the original dictionary
for i, v in d.items():
# sort the values of a list by the letters : a, b ..
v = sorted(v, key=lambda x: x[-1])
summed_groups = []
# groupby the elements of a list by the letters: a, b ..
for j, k in groupby(v, key=lambda x:x[-1]):
# sum the int part of each group
sum_ints = sum([int(x.replace(j,'')) for x in k])
# prepare the results
summed_groups.append("{}{}".format(sum_ints,j))
d[i] = summed_groups
Results :
Out[13]: {1: ['7a', '6b', '3c'], 2: ['7a', '6b', '3c']}
You can use itertools.groupby
:
import itertools
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
new_items = {a:[(c, list(d)) for c, d in itertools.groupby(sorted(b, key=lambda x:x[-1]), key=lambda x:x[-1])] for a, b in items.items()}
final_items = {a:[str(sum(int(i[0]) for i in d))+c for c, d in b] for a, b in new_items.items()}
Output:
{1: ['7a', '6b', '3c'], 2: ['7a', '6b', '3c']}
Here's one solution that uses Counter
s to pre-process the original items
dictionary, then the result is built from a dictionary with Counter
s as values.
>>> from collections import Counter
>>> items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
>>> tmp = {k: Counter(''.join(int(x[:-1])*x[-1] for x in v)) for k,v in items.items()}
>>> {k:[str(vv)+kk for kk,vv in v.items()] for k,v in tmp.items()}
{1: ['7a', '3c', '6b'], 2: ['7a', '3c', '6b']}
import pandas as pd
items = {1: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b'], 2: ['1a', '3c', '2a', '1b', '2a', '1b', '1a', '2b', '1a', '2b']}
for key in items:
s = pd.Series(items[key])
items[key] = [str(v.str[0].astype(int).sum())+k for k,v in s.groupby(s.str[1])]
print(items)
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.