简体   繁体   中英

Add same alphanumeric values in dictionary list python

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM