a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
实际输出:[1,3,5,6] 预期输出:[1,3,5]
如何在两个列表上实现布尔AND操作(列表交集)?
a = [1,2,3,4,5]
b = [1,3,5,6]
c = a and b
print c
实际输出:[1,3,5,6] 预期输出:[1,3,5]
如何在两个列表上实现布尔AND操作(列表交集)?
当前回答
这里的大多数解决方案都不考虑列表中元素的顺序,而是将列表视为集合。另一方面,如果希望找到两个列表中包含的一个最长子序列,则可以尝试以下代码。
def intersect(a, b):
if a == [] or b == []:
return []
inter_1 = intersect(a[1:], b)
if a[0] in b:
idx = b.index(a[0])
inter_2 = [a[0]] + intersect(a[1:], b[idx+1:])
if len(inter_1) <= len(inter_2):
return inter_2
return inter_1
对于a=[1,2,3]和b=[3,1,4,2],返回[1,2]而不是[1,2,3]。注意,这样的子序列不是唯一的,因为[1],[2],[3]都是a=[1,2,3]和b=[3,2,1]的解。
其他回答
使用过滤器和lambda运算符可以实现函数式的方法。
list1 = [1,2,3,4,5,6]
list2 = [2,4,6,9,10]
>>> list(filter(lambda x:x in list1, list2))
[2, 4, 6]
编辑:它过滤掉了同时存在于list1和list中的x,集差异也可以使用:
>>> list(filter(lambda x:x not in list1, list2))
[9,10]
python3 filter返回一个过滤器对象,用list封装它返回输出列表。
如果你将两个列表中较大的一个转换为一个集合,你可以使用intersection()获得该集合与任何可迭代对象的交集:
a = [1,2,3,4,5]
b = [1,3,5,6]
set(a).intersection(b)
对我来说,使用列表推导式是一个非常明显的方法。不确定性能如何,但至少能保持列表。
[x for x in a if x in b]
或者"所有在A中的x值,如果x值在B中"
这可能是晚了,但我只是认为我应该分享的情况下,你需要手动做(显示工作-哈哈)或当你需要所有元素出现尽可能多的次数或当你也需要它是唯一的。
请注意,还为它编写了测试。
from nose.tools import assert_equal
'''
Given two lists, print out the list of overlapping elements
'''
def overlap(l_a, l_b):
'''
compare the two lists l_a and l_b and return the overlapping
elements (intersecting) between the two
'''
#edge case is when they are the same lists
if l_a == l_b:
return [] #no overlapping elements
output = []
if len(l_a) == len(l_b):
for i in range(l_a): #same length so either one applies
if l_a[i] in l_b:
output.append(l_a[i])
#found all by now
#return output #if repetition does not matter
return list(set(output))
else:
#find the smallest and largest lists and go with that
sm = l_a if len(l_a) len(l_b) else l_b
for i in range(len(sm)):
if sm[i] in lg:
output.append(sm[i])
#return output #if repetition does not matter
return list(set(output))
## Test the Above Implementation
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
exp = [1, 2, 3, 5, 8, 13]
c = [4, 4, 5, 6]
d = [5, 7, 4, 8 ,6 ] #assuming it is not ordered
exp2 = [4, 5, 6]
class TestOverlap(object):
def test(self, sol):
t = sol(a, b)
assert_equal(t, exp)
print('Comparing the two lists produces')
print(t)
t = sol(c, d)
assert_equal(t, exp2)
print('Comparing the two lists produces')
print(t)
print('All Tests Passed!!')
t = TestOverlap()
t.test(overlap)
从较大的集合中创建一个集合:
_auxset = set(a)
然后,
c = [x for x in b if x in _auxset]
会做你想做的(保留b的顺序,而不是a的顺序——不一定能同时保留两者),而且动作要快。(使用a中的if x作为列表理解中的条件也可以工作,并且避免了构建_auxset的需要,但不幸的是,对于相当长的列表,它会慢得多)。
如果你想对结果进行排序,而不是保持列表的顺序,一个更整洁的方法可能是:
c = sorted(set(a).intersection(b))