user3843673
user3843673

Reputation: 31

Collapse a list of lists, grouping on specific element and appending other elements

How could I transform a list such as:

l=[ ['A', 'C21'], ['A','D43'],['B','D34'],['C','D45'],['C',D56']

to:

[ ['A','C21 D43'], ['B','D34'],['C','D45 D56'] ]

Where the grouping is performed according to element #0 of each sub list and elements #1 are string concatenated within each group?

Upvotes: 1

Views: 95

Answers (2)

Jon Clements
Jon Clements

Reputation: 142206

If the keys are contiguous then you can use itertools.groupby, eg:

from itertools import groupby

data =[ ['A', 'C21'], ['A','D43'],['B','D34'],['C','D45'],['C','D56'] ]
new_data = [[k, ' '.join(el[1] for el in g)] for k, g in groupby(data, lambda L: L[0])]
# [['A', 'C21 D43'], ['B', 'D34'], ['C', 'D45 D56']]

If not and order doesn't really matter, then:

from collections import defaultdict

dd = defaultdict(list)
for key, val in data:
    dd[key].append(val)

new_data = [[k, ' '.join(v)] for k,v in dd.items()]
# [['B', 'D34'], ['C', 'D45 D56'], ['A', 'C21 D43']]

Alternatively - make use of dict.setdefault, eg:

d = {}
for key, val in data:
    d.setdefault(key, []).append(val)
new_data = [[k, ' '.join(v)] for k,v in d.items()]

Or, if the keys aren't contiguous, but the output should maintain the order of the input, then use collections.OrderedDict, eg:

from collections import OrderedDict

d = OrderedDict()
for key, val in data:
    d.setdefault(key, []).append(val)

new_data = [[k, ' '.join(v)] for k,v in d.items()]
# [['A', 'C21 D43'], ['B', 'D34'], ['C', 'D45 D56']]

Upvotes: 2

pnv
pnv

Reputation: 3145

Try this :

l=[ ['A', 'C21'], ['A','D43'],['B','D34'],['C','D45'],['C','D56']]
x = {}

for a in l:
    if a[0] not in x.keys():
        x[a[0]] = [a[1]]
    else:
        x[a[0]].append(a[1])

print x

array_result = []
for keys, vals in x.iteritems():
    array_result.append([keys, ' '.join(vals)])

print array_result

Upvotes: 3

Related Questions