【问题标题】:Delete both repeated elements from a list of lists in Python从 Python 中的列表列表中删除两个重复的元素
【发布时间】:2018-08-08 06:45:47
【问题描述】:

我有清单

输入:
L = [[1, 2, 3], [2, 3, 4], [5, 6, 7], [2, 3, 4], [2, 3, 5], [1, 2, 3], [1, 2, 3]]

输出:
L= [[5, 6, 7], [ 2, 3, 5]]

我想检查是否L[i]== L[j],然后我会从列表中删除L[j]

你能帮帮我吗?

这是我的代码:

for i in range(0,len(L) - 1):
    for j in range(1,len(L) - 1):
        if (L[i] == L[j]):
            L.remove(L[j])

print(L)

但它给出了一个错误:

if (L[i] == L[j]):
IndexError: list index out of range

【问题讨论】:

  • 所以您想从列表中删除L1,并将L2 添加到列表中?如果是这样:L.remove(L1); L.append(L2).
  • 但是需要检查L1是否在列表中,L2是否不在列表中

标签: python python-3.x python-2.7


【解决方案1】:

删除L 的元素后,L 的形状会发生变化。这就是为什么您得到索引超出范围错误的原因:您仍在迭代 L 的原始长度,但是一旦您开始从 L 中删除元素,它就会变得比这更短。

您可以通过使用count 创建一个新列表来解决此问题:

L2 = [sublist for sublist in L if L.count(sublist) == 1]

print(L2)
>>> [[5, 6, 7], [2, 3, 5]]

注意:您当前的逻辑,即使它适应了 L 的变化长度,也不会返回您想要的输出。它仍然会保留所有重复元素的第一个“副本”,如下面的Richard Rublev's answer 产生的那样。


如果这太慢 (O(n2)),这里是使用 Counter 的 O(n) 解决方案:

from collections import Counter

# Converting elements to hashable type
L = [tuple(sublist) for sublist in L]
cnt = Counter(L)

# Grabbing non-duplicated items
L2 = [k for k, v in cnt.items() if v == 1]

# Converting elements back to lists
L2 = [list(sublist) for sublist in L2]

print(L2)   
>>> [[5, 6, 7], [2, 3, 5]]

【讨论】:

  • 但是当我运行一个巨大的列表时它太慢了,
  • @tdp 添加了替代解决方案。
【解决方案2】:

试试这个

testdata = [[1, 2, 3], [2, 3, 4], [5, 6, 7], [2, 3, 4], [2, 3, 5], [1, 2, 3], [1, 2, 3]]
unique = [list(x) for x in set(tuple(x) for x in testdata)]

结果

[[2, 3, 5], [2, 3, 4], [5, 6, 7], [1, 2, 3]]

【讨论】:

  • 这样做的副作用是它不保持秩序。
  • 虽然这遵循 OP 代码中的逻辑:I want to check if L[i]== L[j], then I will remove L[j] from the list,但从标题和 expected output 来看,我怀疑 OP 真的希望删除 所有 重复条目 - 而不仅仅是额外的条目副本。
  • 是的,我弄错了,我现在看到他要删除重复项。
  • 但这不是我想要的输出,我认为输出中没有 [2,3,4] 和 [1,2,3]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2018-01-01
  • 2020-11-02
  • 1970-01-01
相关资源
最近更新 更多