Python根据第一个或第二个值从列表列表中删除匹配项

时间:2014-10-02 21:32:33

标签: python list dictionary itertools

我有以下列表,我需要删除第一个或第二个值与任何其他第一个或第二个值匹配的任何条目。例如,参见下面的示例和正确的输出。

集合:

+       [0] (['1', '12'], ['1', '8'], ['12', '12']) tuple
+       [1] (['1', '12'], ['1', '8'], ['12', '8'])  tuple
+       [2] (['1', '12'], ['1', '8'], ['12', '0'])  tuple
+       [3] (['1', '12'], ['1', '8'], ['15', '0'])  tuple
+       [4] (['1', '12'], ['12', '12'], ['12', '8'])    tuple
+       [5] (['1', '12'], ['12', '12'], ['12', '0'])    tuple
+       [6] (['1', '12'], ['12', '12'], ['15', '0'])    tuple
+       [7] (['1', '12'], ['12', '8'], ['12', '0']) tuple
+       [8] (['1', '12'], ['12', '8'], ['15', '0']) tuple
+       [9] (['1', '12'], ['12', '0'], ['15', '0']) tuple
+       [10]    (['1', '8'], ['12', '12'], ['12', '8']) tuple
+       [11]    (['1', '8'], ['12', '12'], ['12', '0']) tuple
+       [12]    (['1', '8'], ['12', '12'], ['15', '0']) tuple
+       [13]    (['1', '8'], ['12', '8'], ['12', '0'])  tuple
+       [14]    (['1', '8'], ['12', '8'], ['15', '0'])  tuple
+       [15]    (['1', '8'], ['12', '0'], ['15', '0'])  tuple
+       [16]    (['12', '12'], ['12', '8'], ['12', '0'])    tuple
+       [17]    (['12', '12'], ['12', '8'], ['15', '0'])    tuple
+       [18]    (['12', '12'], ['12', '0'], ['15', '0'])    tuple
+       [19]    (['12', '8'], ['12', '0'], ['15', '0']) tuple

例如:

+       [0] (['1', '12'], ['1', '8'], ['12', '12']) tuple

不起作用,因为'1'在第1对和第2对的第一个位置匹配'1'而'12'在第1对和第3对的第二个位置匹配'12'。

+       [12]    (['1', '8'], ['12', '12'], ['15', '0']) tuple

有效,因为没有第一个值等于任何其他第一个值,没有第二个值等于任何其他第二个值。

需要结果列表(或任何最合适的数据类型):

+       [12]    (['1', '8'], ['12', '12'], ['15', '0']) tuple
+       [8] (['1', '12'], ['12', '8'], ['15', '0']) tuple

我在几个小时后陷入困境。

2 个答案:

答案 0 :(得分:2)

使用列表理解:

>>> [i for i in l if all([len(set(k))==3 for k in zip(*i)])]
[(['1', '12'], ['12', '8'], ['15', '0']), (['1', '8'], ['12', '12'], ['15', '0'])]

如果您还想要索引,请使用enumerate

>>> [j for j,i in enumerate(l) if all([len(set(k))==3 for k in zip(*i)])]
[8, 12]

对于列表中的每个项目,您压缩元组(zip(*i))并使用集合(len(set(k)==3?)检查所有项目是否为不同项。

在第0和第8项:

>>> zip(*l[0])
[('1', '1', '12'), ('12', '8', '12')]
>>> [len(set(k)) for k in zip(*l[0])]
[2, 2]
>>> zip(*l[8])
[('1', '12', '15'), ('12', '8', '0')]
>>> [len(set(k)) for k in zip(*l[8])]
[3, 3]

然后all会检查此列表中的所有项目是True,即==3

>>> [len(set(k))==3 for k in zip(*l[0])]
[False, False]
>>> all([len(set(k))==3 for k in zip(*l[0])])
False
>>> [len(set(k))==3 for k in zip(*l[8])]
[True, True]
>>> all([len(set(k))==3 for k in zip(*l[8])])
True

如果您不想硬编码==3,可以使用==len(k)

答案 1 :(得分:0)

我初始化了一个变量来模拟正确的数据。 如果我理解你想要的东西,下面的代码可能会有用。

a = [(['1', '12'], ['1', '8'], ['12', '12']), (['1', '12'], ['1', '8'], ['12', '8']) , (['1', '12'], ['12', '8'], ['15', '0'])]
len1 = len(a)
len2 = len1 - 1
while(len1 != len2) : 
    len1 = len(a)
    for i in a : 
        test1 = (i[0][0] == i[1][0]) or  (i[2][0] == i[1][0]) or  (i[0][0] == i[2][0])
        test2 = (i[0][1] == i[1][1]) or  (i[2][1] == i[1][1]) or  (i[0][1] == i[2][1])
        if (test1 or test2) :
            a.remove(i)
        len2 = len(a)
print(a)

电子