使用
def compare_lsts(list1,list2):
first_set = set(list1)
second_set=set(list2)
results =[x for x in list1 if x in list2]
print(results)
并且运行compare_lsts([1,2,3,4,5],[3,8,9,1,7])
会给出两个集合中包含的数字,即[1,3]
。
但是,制作列表1包含多个列表,例如compare_lsts([[1,2,3,4,5],[5,8,2,9,12],[3,7,19,4,16]],[3,7,2,16,19])
给出[],[],[]
。
我在list1中使用了list,然后是循环的结果。我显然不知道自己在做什么。
基本上问题是:如何将一个静态列表中的项目与列表中的项目进行比较?
答案 0 :(得分:1)
首先,您已经开始使用集合,所以您一定要使用它们,因为它们在检查包含时速度更快。此外,对于集合已经有一些有用的内置功能,因此为了比较两个列表,您可以只是将这些集合相交以获取两个列表中的那些项目:
>>> set1 = set([1, 2, 3, 4, 5])
>>> set2 = set([3, 8, 9, 1, 7])
>>> set1 & set2
{1, 3}
>>> list(set1 & set2) # in case you need a list as the output
[1, 3]
同样,你也可以找到两个集合的联合来获取任何集合中的那些项目:
>>> set1 | set2
{1, 2, 3, 4, 5, 7, 8, 9}
因此,如果要查找list2中任何list1子列表中的所有项目,那么您可以将所有子列表与list2相交,然后将所有这些结果联合起来:
>>> sublists = [set([1, 2, 3, 4, 5]), set([5, 8, 2, 9, 12]), set([3, 7, 19, 4, 16])]
>>> otherset = set([3, 7, 2, 16, 19])
>>> intersections = [sublist & otherset for sublist in sublists]
>>> intersections
[{2, 3}, {2}, {16, 3, 19, 7}]
>>> union = set()
>>> for intersection in intersections:
union = union | intersection
>>> union
{16, 19, 2, 3, 7}
使用functools.reduce
:
>>> import functools
>>> functools.reduce(set.union, intersections)
{16, 19, 2, 3, 7}
同样,如果你想实际交叉那些结果,你也可以这样做:
>>> functools.reduce(set.intersection, intersections)
set()
最后,你可以将这一切打包成一个很好的功能:
def compareLists (mainList, *otherLists):
mainSet = set(mainList)
otherSets = [set(otherList) for otherList in otherLists]
intersections = [mainSet & otherSet for otherSet in otherSets]
return functools.reduce(set.union, intersections) # or replace with set.intersection
并像这样使用它:
>>> compareLists([1, 2, 3, 4, 5], [3, 8, 9, 1, 7])
{1, 3}
>>> compareLists([3, 7, 2, 16, 19], [1, 2, 3, 4, 5], [5, 8, 2, 9, 12], [3, 7, 19, 4, 16])
{16, 19, 2, 3, 7}
请注意,我替换了函数中参数的顺序,因此首先提到主列表(在您的情况下为 list2 ),因为那是与其他人进行比较的那个。
答案 1 :(得分:0)
不确定这是否是最佳方式,但是:
def flat(l):
c_l = []
for i in l:
if isinstance(i,list):
map(c_l.append,i)
else:
c_l.append(i)
return c_l
def compare_lsts(a,b):
if all([True if isinstance(x,list) else False for x in a]): #if there is sublists in a
a = flat(a) #flats a
if all([True if isinstance(x,list) else False for x in b]): #if there is sublists in b
b = flat(b) #flats b
return list(set(a) & set(b)) #intersection between a and b
print (compare_lsts([[1,2,3,4,5],[5,8,2,9,12],[3,7,19,4,16]],[3,7,2,16,19]) #[16, 3, 2, 19, 7])
答案 2 :(得分:0)
如果您正在追踪第一个所有列表中的元素:
set(first).intersection(second, third) # fourth, fifth, etc...
>>> set([1, 2, 3]).intersection([2, 3, 4], [3, 4, 5])
set([3])
如果您正在追踪第一个任何其他列表中的元素:
>>> set([1, 2, 3]) & set([4]).union([5])
set([2])
那么,那就是一个简单的函数:
def in_all(fst, *rst):
return set(fst).intersection(*rst)
def in_any(fst, *rst):
it = iter(rst)
return set(fst) & set(next(it, [])).union(*it)