如何通过迭代集合中的元素来删除集合中的特定元素?

时间:2020-04-13 14:52:02

标签: python

因此,我有一个列表(subject1,relationtype,sobject2)的元组列表,表示关系事实。我想写一个删除(subject1,relationtype,sobject2)(subject2,relationtype,sobject1)中的一个(如果它们都在列表中)的方法。

这是我尝试过的:

def delete_symmetric_relations(A):
    A = set(tuple(e) for e in A)
    for (s,r,o) in A:
        for (s1, r1, o1) in A:
            if (s,r,o)==(o1,r1,s1) and (s,r,o) != (s1,r1,o1):
                A.remove((s1,r1,o1))
    return list(A)

print(delete_symmetric_relations(data)) 

然后我得到了错误: RuntimeError:设置迭代期间更改的大小

该方法如何工作的示例: 假设我们有列表[(1,in_same_numbersystem_as,3),(2,"is_smaller_than",4),(3,in_same_numbersystem_as,1),(2,"is_smaller_than",6)],则该方法应返回[(2,"is_smaller_than",4),(3,in_same_numbersystem_as,1),(2,"is_smaller_than",6)][(1,in_same_numbersystem_as,3),(2,"is_smaller_than",4),(2,"is_smaller_than",6)]中的一个 因此,根据建议,我将代码重写为:

def delete_symmetric_relations(A):
    somelist = [(s,r,o) for (s,r,o) in A if (o,r,s) not in A]
    return somelist

但是此代码删除了所有(s,r,o)和(o,r,s),但我想保留至少一个。并得到:

IOPub data rate exceeded.
The notebook server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--NotebookApp.iopub_data_rate_limit`

因为我的清单非常大。

那我该怎么办?

2 个答案:

答案 0 :(得分:1)

更新: 我最初误解了这个问题。基本概念仍然存在。不要尝试更改您要遍历的列表。而是制作一个副本进行变异。然后遍历原始列表。您可以进行所需的任何比较。

def remove_symetric(A):

    B = A
    for (a, b, c) in A:
        if (c,b,a) in B:
            B.remove((c,b,a))

    return B

A = [(0, 1, 3), (0, 1, 3), (0, 2, 3), (0, 1, 4), (5, 1, 3), (0, 7, 3), (0, 7, 3),(3, 1, 0)]
A=remove_symetric(A)
print("Non-duplicate items:")
print(A)

输出:

Non-duplicate items:
[(0, 1, 3), (0, 1, 3), (0, 2, 3), (0, 1, 4), (5, 1, 3), (0, 7, 3), (0, 7, 3)]

原始答案:

而不是删除重复项。如果尚未添加,请尝试添加到空白列表。像这样:

def return_unique(A):

    B = []
    for x in A:
       if x not in B:
           B.append(x)
    return B

像这样测试:

A = [(0, 1, 3), (0, 1, 3), (0, 2, 3), (0, 1, 4), (5, 1, 3), (0, 7, 3), (0, 7, 3)]
B = return_unique(A)
print('Non-duplicate items:')
print(B)
Non-duplicate items:
[(0, 1, 3), (0, 2, 3), (0, 1, 4), (5, 1, 3), (0, 7, 3)]

答案 1 :(得分:1)

您可以对列表中的每个元组进行排序,并将最终输出传递到集合中,从而删除重复项

>>> data = [(0,1,7), (5,1,3), (7,1,0), (0,7,1)]  # sample input

>>> data = list(set(map(lambda x: tuple(sorted(x)), data)))
[(1, 3, 5), (0, 1, 7)]

注意:仅当您的tuple必须具有唯一的type object时,以上解决方案才有效。 如果您的元组包含不同的type对象的混合,那么您需要将tuple中的所有元素转换为string类型,并将其传递到sorted方法中。

>>> data = [(0, 1, 7, 'b'), (5, 1, 3, 'a'), (7, 1, 0, 'b'), (0, 1, 7, 'b')]
>>> list(set(map(lambda x: tuple(sorted(map(str, x))), data)))
[('1', '3', '5', 'a'), ('0', '1', '7', 'b')]
相关问题