如何在Python中合并列表中重复的元素?

3

我有一个坐标列表,例如:

list_coordinate =[(9,0),(9,1),(9,3) ... (53,0),(53,1),(53,3)...(54,0),(54,1)..]

value = []

 for m in range(0,len(list_coordinate)):    
    if m != len(list_coordinate)-1:
        if list_coordinate[m][0]==list_coordinate[m+1][0]:
            value.append(list_coordinate[m][0])`

这段代码的输出结果是:
value = [9,9 ,9,...,53,53,53,...,54,54,54,54...]

我希望将此值列表合并为相似元素,并期望输出如下: 预期输出:
 [9,53,54]

1
为什么不使用set(value),但它不按输入顺序输出? - The6thSense
4个回答

4

您可以使用 itertools.groupby 函数。

from itertools import groupby
value = [9,9 ,9,53,53,53,54,54,54,54]
g = [k for k,_ in groupby(value)]
print(g)

产生的是:
[9, 53, 54]

并且保证输出结果与输入列表的顺序相同(如果有关系的话)。

基本上

groupby(iterable[, keyfunc])

将可迭代对象中的元素分组,当关键函数发生变化时,将传递到新的组。

如果省略了关键函数,则假定为身份函数,并且组的关键字将是遇到的每个元素。

因此,只要value中的元素保持不变,它们就会在同一个键下分组,该键是元素本身。

注意:这仅适用于连续重复。如果您想要摆脱重复出现的重复项,则应首先对列表进行排序(如groupby 文档所述)

根据您下面的评论,如果您想直接操作坐标

list_coordinate = [(9,0), (9,1), (9,3), (53,0), (53,1), (53,3), (54,0), (54,1)]
g = [k for k,_ in groupby(list_coordinate, lambda x: x[0])]
print(g)

生成相同的输出

[9, 53, 54]

非常感谢@ Pynchia!我确实遇到了groupby,但是无法弄清如何使用它。那么,如果不提取第一个元素,我是否也可以对list_coordinate执行相同的操作? - DarshanJoshi
@AnandSKumar,为什么他们在Py3中弃用了这样美丽的语法?我认为相比之下x[0]太可怕了。 - Pynchia
@Pynchia 我在我的OpenCV程序中基本上是在寻找检测到的表面的坐标线。我需要X坐标。因此,直接使用groupby或Salman建议的方法提供了我所需的结果。我正在查阅groupby文档。即使是list(set(map))也给了我所需的结果。谢谢! - DarshanJoshi
好的,与集合的区别在于输出的顺序是否重要。我描述了groupby如何工作,因为我认为官方文档有些枯燥,并且可以更详细地阐述。 - Pynchia
那么使用groupby,我可以将相差2的3个元素分组吗?我的意思是,如果我有列表[2, 67, 4, 69, 92, 66, 109, 68, 98, 59, 60],我能否将其分组为[(2,4), (59,60,66,67,68,69), (92,98,109)]? - DarshanJoshi
显示剩余5条评论

3
如果你喜欢一行代码的写法,可以这样做:
list(set(map(lambda x: x[0], list_coordinate)))

它将输出:
[9, 53, 54]

注意:由于代码中使用了 set,因此这里不能保证元素的顺序。

1
请注意,这并不保证元素的顺序。 - Anand S Kumar

1
您可以使用一个OrderedDict来处理您这两种情况。首先只处理x坐标:
list_coords = [(9, 0), (9, 1), (9, 3), (53, 0), (53, 1), (53, 3), (54, 0), (54, 1)]
merged = OrderedDict()

for coord in list_coords:
    merged[coord[0]] = 1

print merged.keys()

给予:
[9, 53, 54]

请注意,例如(9, 0)稍后重复出现不会改变输出结果。
其次,对于整个坐标系。请注意,数据中(10, 0)重复出现了3次:
list_coords = [(9, 0), (9, 1), (9, 3), (10, 0), (10, 0), (10, 0), (53, 0), (53, 1), (53, 3), (54, 0), (54, 1)]
merged = OrderedDict()

for coord in list_coords:
    merged[coord] = 1

print merged.keys()

给予:

[(9, 0), (9, 1), (9, 3), (10, 0), (53, 0), (53, 1), (53, 3), (54, 0), (54, 1)]

我通过你的方法学会了使用OrderedDict(),谢谢。基本上列表中的Y坐标是多余的。我想要仅仅分组X坐标,并且取特定范围内X坐标的平均值。 - DarshanJoshi

0

为什么不使用集合:

{ k[0] for k in list_coordinate }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接