【发布时间】:2018-10-12 04:08:58
【问题描述】:
我有一个看起来像的列表列表
[[1,'a',2],[1,'b',2],[1,'a',3]]
如果列表列表中的第二个元素相同(例如它们都是a),我想从列表中删除该项目
我想创建如下所示的输出:
[[1,'a',2],[1,'b',2]]
它抓取重复列表中的第一个。
【问题讨论】:
标签: python
我有一个看起来像的列表列表
[[1,'a',2],[1,'b',2],[1,'a',3]]
如果列表列表中的第二个元素相同(例如它们都是a),我想从列表中删除该项目
我想创建如下所示的输出:
[[1,'a',2],[1,'b',2]]
它抓取重复列表中的第一个。
【问题讨论】:
标签: python
这是How do you remove duplicates from a list whilst preserving order? 的变体。
您可以使用标记集来跟踪已附加的子列表,因为字符串是不可变的,因此可以散列并存储在 set 中:
lst = [[1,'a',2],[1,'b',2],[1,'a',3]]
marker_set = set()
result = []
for sublist in lst:
second_elt = sublist[1]
if second_elt not in marker_set:
result.append(sublist)
marker_set.add(second_elt)
print(result)
打印:
[[1, 'a', 2], [1, 'b', 2]]
(使用标记set 而不是list 允许平均O(1) 查找而不是O(N))
【讨论】:
set 有什么好处
您可以在列表的背面使用第二个元素为键的字典来删除重复项:
dct = {j: (i, k) for i, j, k in reversed(L)}
{'a': (1, 2), 'b': (1, 2)}
将结果作为列表返回:
[[i, j, k] for j, (i, k) in dct.items()]
[[1, 'a', 2], [1, 'b', 2]]
虽然此解决方案将始终保持第一次出现的重复,但最终结果中不保证元素的相对顺序。
【讨论】:
reversed。这样做更好,因为它不会创建新列表。
dct 可以是任意顺序。
lst = [[1,'a',2],[1,'b',2],[1,'a',3]]
res = []
for i in lst:
if not any(i[1] in j for j in res):
res.append(i)
print(res)
# [[1, 'a', 2], [1, 'b', 2]]
【讨论】:
groupby而排序,效率低下
groupby 真的很整洁。否则 sort 会扼杀乐趣,在 O(N) 这样做时引入无用的 O(N*log(N)) 复杂性