在列表列表中对元素进行分组

时间:2017-03-27 05:36:39

标签: python

我有一些记录如下:

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']]

我希望我的记录看起来像这样:

list2= ['corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale']

我编写了以下代码来完成此任务:

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

如果我在列表中有两个元素并且是连续的条目,则它会起作用,但是如果有两个以上的项目并且不是连续的则会失败。 任何人都可以指出一个合适的方法来实现这一目标。

3 个答案:

答案 0 :(得分:5)

您可以使用dict进行分组。

为了方便起见,defaultdict对于这种情况来说是dict的一个很好的子类:

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)

输出:

[('corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale')]

测试:

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)

输出:

[('corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale | 123456'), ('testing 1243', 'hi')]

如果您需要保留订单,请改为使用OrderedDict

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())

答案 1 :(得分:2)

受到this答案的启发,根据保留的顺序适应您的情况:

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)

输出:

[['corner grant and main reef road, new state area, springs', 'springs | palm springs | edenvale']]

答案 2 :(得分:1)

您可以使用groupby功能对列表中的元素进行分组。

试;

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]