比较两个列表的索引值,并将不相似的值写入Python中的另一个列表

时间:2015-02-17 12:24:03

标签: python arrays list

考虑以下列表:

list_one = ['0414870590', '3965667115', '7686006277', '0736885667', '2580894453', '4890895590']

list_two = [['1', 'acppkbgrfi', '1', '0414870590', 'foo', 'bar'], 
['2', 'zhwgvdwoif', '1', '8201315776', 'foo', 'bar'], 
['3', 'jbimbttwmo', '1', '4366752905', 'foo', 'bar'], 
['4', 'dalroxsqxt', '1', '0652459418', 'foo', 'bar'], 
['5', 'jbygszsfcw', '1', '1876053449', 'foo', 'bar'], 
['6', 'hcbrgydtxx', '1', '1138310041', 'foo', 'bar'], 
['7', 'rlkadtqarj', '1', '7479978778', 'foo', 'bar'], 
['8', 'koafneqxgh', '1', '0539402828', 'foo', 'bar'], 
['9', 'lsaakfoqdf', '1', '0300592696', 'foo', 'bar']]

我想只查找list_one中的条目与list_two[j][3]不相等的条目。 这是我认为会起作用的,因为它似乎是合乎逻辑的,但似乎有缺陷。

list_only_not_similar = []

for i in list_one:
    for j in list_two:
        if i != j[3]:
            list_only_not_similar.append(j)

如果我把一切都做对了,因为只有一场比赛(list_one[0] - > '0414870590'list_two[0][3] - > '0414870590'),表示list_only_not_similar数组的长度为8。 但它是53

>>> len(list_only_not_similar)
53

所以list_only_not_similar中我想要的输出是:

[['2', 'zhwgvdwoif', '1', '8201315776', 'foo', 'bar'], 
['3', 'jbimbttwmo', '1', '4366752905', 'foo', 'bar'], 
['4', 'dalroxsqxt', '1', '0652459418', 'foo', 'bar'], 
['5', 'jbygszsfcw', '1', '1876053449', 'foo', 'bar'], 
['6', 'hcbrgydtxx', '1', '1138310041', 'foo', 'bar'], 
['7', 'rlkadtqarj', '1', '7479978778', 'foo', 'bar'], 
['8', 'koafneqxgh', '1', '0539402828', 'foo', 'bar'], 
['9', 'lsaakfoqdf', '1', '0300592696', 'foo', 'bar']]

4 个答案:

答案 0 :(得分:3)

[sublist for sublist in list_two if sublist[3] not in list_one]

答案 1 :(得分:3)

这是因为对于list_two中的每个值,如果它不等于list_one处的值,则会添加list_two[j][3]中的值。

您可以通过计算list_only_not_similar中每个值的出现次数并将其与list_two的长度进行比较来调整您当前的解决方案。在任何元素中都找不到任何长度相等的东西。

但那太糟糕了,不要那样做

如何解决问题

用英文写

我找到最好的方法来弄清楚如何得到我想要的是写下我会向别人解释的内容:

  

我想要list_twolist_one找不到第三个值的所有值

从那里开始,将其转化为Python并不是一件容易的事情:

values_i_want= []
for value in list_two:
    if not value[3] in list_one:
        values_i_want.append(value)

优化

但是,根据list_onelist_two中的值数量,您可能会发现这需要时间。这是因为在Python中,比较昂贵,如果值不在list_one中,那么您将执行N*N(或O(N { {1}} 2)比较。那是很多。

您可以通过将)更改为集合来大幅减少比较次数:

list_one

由于集合基于哈希值,因此您已将查找更改为每个值的常量时间,因此您需要set_one = set(list_one) 进行N*N比较,而不是N*1

简化(重构)

现在,一旦你有了这个代码做你想做的事情,你可以通过将其变成列表理解来简化,就像Hackaholic所做的那样:

values_I_want = [value for value in list_two if list_two[3] not in set_one]

当然,values_I_want不是最好的变量名,所以你可以这样做:

list_not_similar = [x for x in list_two if x[3] not in set_one]

随着您对语言和编程越来越熟悉,对于像这样的小问题,您可以直接从听到问题跳到编写最终代码,但不要太担心能够做到这一点现在

答案 2 :(得分:0)

您应该交换循环场所并检查每个i元素与每个i元素,并且只有当i元素都不与您感兴趣的字段相同时才将其添加到结果列表中。

list_only_not_similar = []
for j in list_two:
    f = True
    for i in list_one:
        if i == j[3]:
            f = False
            break
    if f:
        list_only_not_similar.append(j)

事实是,您为每个i元素添加了每个合适的j元素,但是您应该针对每个i元素检查每个j元素,并且如果检查了所有i元素,则仅将其添加到结果列表中。还有一个突破,因为如果你发现至少有一个元素相等 - 你不必检查其他元素 - 无论如何这条线都没有结果。

答案 3 :(得分:0)

您不需要遍历list_one,因为简单的IN语句应该足够了:

list_one = ['0414870590', '3965667115', '7686006277', '0736885667', '2580894453', '4890895590']

list_two = [['1', 'acppkbgrfi', '1', '0414870590', 'foo', 'bar'],
            ['2', 'zhwgvdwoif', '1', '8201315776', 'foo', 'bar'],
            ['3', 'jbimbttwmo', '1', '4366752905', 'foo', 'bar'],
            ['4', 'dalroxsqxt', '1', '0652459418', 'foo', 'bar'],
            ['5', 'jbygszsfcw', '1', '1876053449', 'foo', 'bar'],
            ['6', 'hcbrgydtxx', '1', '1138310041', 'foo', 'bar'],
            ['7', 'rlkadtqarj', '1', '7479978778', 'foo', 'bar'],
            ['8', 'koafneqxgh', '1', '0539402828', 'foo', 'bar'],
            ['9', 'lsaakfoqdf', '1', '0300592696', 'foo', 'bar']]

list_only_not_similar = []

# make a set from list for performance purpose
set_one = set(list_one)

for j in list_two:
    if j[3] not in set_one:
        list_only_not_similar.append(j)

print len(list_only_not_similar)

输出将是:

8