从元组列表中删除元组

时间:2017-07-10 00:32:14

标签: python list tuples

我有一个看起来像这样的元组列表;

ListTuples = [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102'), ('192.168.1.100', '192.168.1.103'), ('192.168.1.103', '192.168.1.100')]

我想在元组的第一个元素与另一个元组的第二个元素匹配时删除元组,同时,元组的第二个元素与同一个其他元组的第一个元素匹配。 OutputList看起来像这样;

OutputList = [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102')]

除了遍历所有元组以比较并保存到新的元组列表之外,还有更简单的方法吗?

谢谢。

3 个答案:

答案 0 :(得分:3)

制作两组:第一组具有原始元组,第二组具有元组交换的元组。然后取两组的交集。这些是要删除的元组。创建一个包含所有元组的新列表,但是:

>>> ListTuples = [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102'), ('192.168.1.100', '192.168.1.103'), ('192.168.1.103', '192.168.1.100')]
>>> set1 = set(ListTuples)
>>> set2 = set((e2, e1) for e1, e2 in ListTuples)
>>> to_remove = set1 & set2
>>> to_remove
set([('192.168.1.103', '192.168.1.100'), ('192.168.1.100', '192.168.1.103')])
>>> NewList = [t for t in ListTuples if t not in to_remove]
>>> NewList
[('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102')]

这将是O(n),而搜索列表将是O(n ** 2)。

答案 1 :(得分:1)

好吧,如果你想要将它们相互比较,你必须迭代你的元组,但至少你可以使用带有反向元素的临时集来加快查找速度:

ListTuples = [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102'),
              ('192.168.1.100', '192.168.1.103'), ('192.168.1.103', '192.168.1.100')]

seen = set()
for element in ListTuples:
    if element in seen:
        seen.discard(element)
    else:
        seen.add(tuple(reversed(element)))
OutputList = [tuple(reversed(element)) for element in seen]

print(OutputList)  # [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102')]

它不会保持秩序,但是。

答案 2 :(得分:1)

使用collections.Counter计算每个排序元组发生的次数,然后过滤掉那些计数大于1的元组:

from collections import Counter

ListTuples = [('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102'), ('192.168.1.100', '192.168.1.103'), ('192.168.1.103', '192.168.1.100')]

counts = Counter(tuple(sorted(t)) for t in ListTuples)
OutputList = [k for k in counts if counts[k] == 1]

>>> OutputList
[('192.168.1.100', '192.168.1.101'), ('192.168.1.100', '192.168.1.102')]

请注意,这不会保留原始列表中的项目顺序;在这种情况下,我不知道这对你是否重要。

它对每个元组进行排序也有点低效,但是必须采取一些措施来考虑项目顺序,如果在一般情况下每个元组可以有超过2个元素,那么对元组进行排序将是要走的路。

你可以像这样做一个单行:

OutputList = [k for k, count in Counter(tuple(sorted(t)) for t in ListTuples).items() if count == 1]