我在Python中有两个列表:

temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']

假设每个列表中的元素都是唯一的,我想用第一个列表中的项创建第三个列表,这些项不在第二个列表中:

temp3 = ['Three', 'Four']

有没有没有周期和检查的快速方法?


当前回答

这是另一个解决方案:

def diff(a, b):
    xa = [i for i in set(a) if i not in b]
    xb = [i for i in set(b) if i not in a]
    return xa + xb

其他回答

这可以用一行来解决。 问题给出两个列表(temp1和temp2),在第三个列表(temp3)中返回它们的差值。

temp3 = list(set(temp1).difference(set(temp2)))

如果您想要更类似于变更集的东西……可以使用Counter

from collections import Counter

def diff(a, b):
  """ more verbose than needs to be, for clarity """
  ca, cb = Counter(a), Counter(b)
  to_add = cb - ca
  to_remove = ca - cb
  changes = Counter(to_add)
  changes.subtract(to_remove)
  return changes

lista = ['one', 'three', 'four', 'four', 'one']
listb = ['one', 'two', 'three']

In [127]: diff(lista, listb)
Out[127]: Counter({'two': 1, 'one': -1, 'four': -2})
# in order to go from lista to list b, you need to add a "two", remove a "one", and remove two "four"s

In [128]: diff(listb, lista)
Out[128]: Counter({'four': 2, 'one': 1, 'two': -1})
# in order to go from listb to lista, you must add two "four"s, add a "one", and remove a "two"

现有的解决方案都提供了其中的一个或另一个:

比O(n*m)性能快。 保持输入列表的顺序。

但到目前为止,还没有一种解决方案兼而有之。如果你两者都想要,试试这个:

s = set(temp2)
temp3 = [x for x in temp1 if x not in s]

性能测试

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)

结果:

4.34620224079 # ars' answer
4.2770634955  # This answer
30.7715615392 # matt b's answer

我提出的方法以及保持顺序也比集合减法(稍微)快,因为它不需要构造一个不必要的集合。如果第一个列表比第二个列表长得多,并且散列代价昂贵,那么性能差异将更加明显。下面是第二个测试:

init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''

结果:

11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer

如果散差表的元素是排序和集合的,你可以使用朴素方法。

list1=[1,2,3,4,5]
list2=[1,2,3]

print list1[len(list2):]

或者使用本机set方法:

subset=set(list1).difference(list2)

print subset

import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print "Naive solution: ", timeit.timeit('temp1[len(temp2):]', init, number = 100000)
print "Native set solution: ", timeit.timeit('set(temp1).difference(temp2)', init, number = 100000)

朴素解:0.0787101593292

本机集解决方案:0.998837615564

def diffList(list1, list2):     # returns the difference between two lists.
    if len(list1) > len(list2):
        return (list(set(list1) - set(list2)))
    else:
        return (list(set(list2) - set(list1)))

例如,如果list1 =[10, 15, 20, 25, 30, 35, 40]和list2 =[25, 40, 35],那么返回的列表将输出= [10,20,30,15]