Reputation: 13
I have a list that contains two indices for each entry, along with a value. The first two elements in each tuple are the row and column in the table, respectively. The third item is the cell's value.
I want to merge the values of each of the same cells. Here is an example of the data structure:
[
(1, 2, 'R'),
(1, 3, 'S'),
(1, 2, 'S'),
(2, 3, 'S'),
]
I need to merge the items with matching row/column pairs like this:
[
(1, 2, 'RS'),
(1, 3, 'S'),
(2, 3, 'S'),
]
or:
[
(1, 2, ('R', 'S')),
(1, 3, ('S',)),
(2, 3, ('S',)),
]
Upvotes: 1
Views: 4082
Reputation: 17854
Another implementation using a dictionary:
dct = {}
for *i, j in lst:
dct.setdefault(tuple(i), list()).append(j)
[(*k, tuple(v)) for k, v in dct.items()]
# [(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]
Upvotes: 0
Reputation: 397
In [1]: a=[(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
...: b={}
...: for i in a:
...: try:
...: b[i[0:2]] += (i[2],)
...: except(KeyError):
...: b[i[0:2]] = (i[2],)
...: c=[k + (v,) for k, v in b.items()]
...:
In [2]: a
Out[2]: [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
In [3]: b
Out[3]: {(1, 2): ('R', 'S'), (1, 3): ('S',), (2, 3): ('S',)}
In [4]: c
Out[4]: [(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]
Upvotes: 0
Reputation: 123491
Here's something that should work. If you're using Python 3, change the.iteritems()
method calls to just.items()
(which is already an iterator in that version of Python).
from collections import defaultdict
def merge_final_values(values):
mergeddict = defaultdict(list)
for group in values:
mergeddict[group[:-1]].append(group[-1])
return [(k + (tuple(v),) if len(v) > 1 else k + tuple(v))
for k, v in mergeddict.iteritems()]
test = [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
print(merge_final_values(test))
Output:
[(1, 2, ('R', 'S')), (1, 3, 'S'), (2, 3, 'S')]
if you want the merged values concatenated into a single string, just change the return value of the function to:
return [(k + (''.join(v),)) for k, v in mergeddict.iteritems()]
And you'll get this output instead:
[(1, 2, 'RS'), (1, 3, 'S'), (2, 3, 'S')]
Upvotes: 1
Reputation: 107337
You can use itertools.groupby()
:
>>> from itertools import groupby
>>> l = [(1, 2, 'R'), (1, 3, 'S'), (1, 2, 'S'), (2, 3, 'S')]
>>> g_list=[list(g) for k, g in groupby(sorted(l),lambda x :x[0:2])]
>>> [(i[0],j[0],k) for i,j,k in [zip(*i) for i in g_list]]
[(1, 2, ('R', 'S')), (1, 3, ('S',)), (2, 3, ('S',))]
in this snippet we first need to sort our list with sorted()
function that that sort our tuplse based on those elements , so we have this result :
>>> sorted(l)
[(1, 2, 'R'), (1, 2, 'S'), (1, 3, 'S'), (2, 3, 'S')]
then we grouping the sorted list based on first tow element (lambda x :x[0:2]
) so we would have :
>>> g_list
[[(1, 2, 'R'), (1, 2, 'S')], [(1, 3, 'S')], [(2, 3, 'S')]]
So now we have a nested list with same 2 first element , now we need to keep just one of 1th and 2th element and both (or more) 3th elements , in this situation we could use zip()
function that will have this results :
>>> [zip(*i) for i in g_list]
[[(1, 1), (2, 2), ('R', 'S')], [(1,), (3,), ('S',)], [(2,), (3,), ('S',)]]
now what we need is chose the 0th element of first and second tuples and whole of 3th elemnt :
(i[0],j[0],k) for i,j,k in ...
Upvotes: 3