Reputation: 1037
I have a few records which reads as follows:
list1= [['corner grant and main reef road, new state area, springs', 'springs'],
['corner grant and main reef road, new state area, springs', 'palm springs'],
['corner grant and main reef road, new state area, springs', 'edenvale']]
I want my record to look like this:
list2= ['corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale']
I wrote the following code to accomplish this:
for i in range(len(list1)-1):
if list1[i][0] == list1[i+1][0]:
list2.append([list1[i][0], list1[i][1] + "|" + list1[i + 1][1]])
else:
pass
This works if I have two elements in a list and are consecutive entries, it however fails if there are more than 2 items and are not consecutive. Could anyone please point out a suitable way to accomplish this.
Upvotes: 2
Views: 3534
Reputation: 2006
You can use a dict
for grouping.
To make things easier defaultdict
is a good sub-class of dict
for this case:
from collections import defaultdict
list1= [['corner grant and main reef road, new state area, springs', 'springs'],
['corner grant and main reef road, new state area, springs', 'palm springs'],
['corner grant and main reef road, new state area, springs', 'edenvale']]
def grouping(l):
d = defaultdict(list)
for key,value in l:
d[key].append(value)
for key in d:
d[key] = ' | '.join(d[key])
return list(d.items())
list2 = grouping(list1)
print(list2)
Output:
[('corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale')]
Testing:
list3= [['corner grant and main reef road, new state area, springs', 'springs'],
['corner grant and main reef road, new state area, springs', 'palm springs'],
['corner grant and main reef road, new state area, springs', 'edenvale'],
['testing 1243','hi'],
['corner grant and main reef road, new state area, springs', '123456'],
]
print(grouping(list3)
Output:
[('corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale | 123456'), ('testing 1243', 'hi')]
If you need to preserve the order, use OrderedDict
instead:
from collections import OrderedDict
def grouping(l):
d = OrderedDict()
for key,value in l:
d.setdefault(key, []).append(value)
for key in d:
d[key] = ' | '.join(d[key])
return list(d.items())
Upvotes: 5
Reputation: 9335
You can use groupby
funciton to group the elements in the list.
try;
from itertools import groupby
list1 = ....
grp = groupby(sorted(list1, key=lambda x: x[0]), lambda x: x[0])
list2 = [(key, " | ".join([x for _, x in group])) for key, group in grp]
Upvotes: 2
Reputation: 5454
Inspired from this answer, adapted for your case with preserved order:
list1 = [['corner grant and main reef road, new state area, springs', 'springs'],
['corner grant and main reef road, new state area, springs', 'palm springs'],
['corner grant and main reef road, new state area, springs', 'edenvale']]
from itertools import groupby
from operator import itemgetter
list2 = []
for _, v in groupby(sorted(list1, key=itemgetter(0)), key=itemgetter(0)):
v = list(v)
cols = " | ".join([sub[1] for sub in v])
list2.append([v[0][0], cols])
print(list2)
output:
[['corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale']]
Upvotes: 2