0

使用

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)

和 runningcompare_lsts([1,2,3,4,5],[3,8,9,1,7])给出了两组中包含的数字,即[1,3]

但是,使列表 1 包含超过 1 个列表,例如compare_lsts([[1,2,3,4,5],[5,8,2,9,12],[3,7,19,4,16]],[3,7,2,16,19])给出[],[],[]

我在 list1 中使用了列表,然后是循环的结果。我显然不知道我在做什么。

基本上问题是:如何将一个静态列表中的项目与尽可能多的列表进行比较?

4

3 回答 3

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),因为这是与其他列表进行比较的列表。

于 2012-11-21T18:23:05.963 回答
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])
于 2012-11-21T18:19:54.017 回答
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)
于 2012-11-21T18:37:49.253 回答