Python:确定未列出的列表是否包含在“列表列表”中,而不管元素的顺序如何

时间:2013-11-18 18:42:36

标签: python performance list sorted

我对这个问题提出了类似的问题:Determine if 2 lists have the same elements, regardless of order?

确定未列出的列表list1是否包含在“列表列表”myListOfLists中的最佳/最快方式是什么,无论list1中元素的顺序如何?我的尝试被包含在我多次调用的函数doSomething(...)中:

def doSomething(myListOfLists, otherInputs):

    list1 = []
    ...  # do something here with `otherInputs' 
    ...  # which gives `list1' some values

    # now only append `list1' to `myListOfLists' if it doesn't already exist
    # and if it does exist, remove it

    removeFromList = False
    for myList in myListOfLists:
        if sorted(list1) == sorted(myList):
            removeFromList = True
            break

    if removeFromList:
        myListOfLists.remove(list1)
    else:
        myListOfLists.append(list1)

    return myListOfLists

这个问题是我需要运行函数doSomething(...)大约1.0e5次。随着myListOfLists的每次调用doSomething(...)越来越大,这变得非常耗时。

编辑:

对任务的一些澄清。让我举一个例子来说明所需的输出:

a = []
doSomething(a, [1,2,3])
>> a = [1,2,3]

由于[1,2,3]不在a,因此会附加到a

doSomething(a, [3,4,5])
>> a = [[1,2,3], [3,4,5]]

由于[3,4,5]不在a,因此会附加到a

doSomething(a, [1,2,3])
>>[3,4,5]

由于[1,2,3]中的a ,它将从a中删除。

编辑:

所有列表都有相同的长度。

4 个答案:

答案 0 :(得分:3)

您可以在此处使用套装:

def doSomething(myListOfLists, otherInputs):
    s = set(otherInputs)           #create set from otherInputs
    for item in myListOfLists: 
        #remove the common items between `s` and current sublist from `s`.
        s -= s.intersection(item) 
        #if `s` is empty, means all items found. Return True
        if not s:                  
            return True
    return not bool(s)
... 
>>> doSomething([[1, 2, 7],[6, 5, 4], [10, 9, 10]], [7, 6, 8])
False
>>> doSomething([[1, 2, 7],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
True

更新1:任何子列表都包含与otherInputs完全相同的项目。

def doSomething(myListOfLists, otherInputs):
    s = set(otherInputs)
    return any(set(item) == s for item in myListOfLists)
... 
>>> doSomething([[6, 8, 7],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
True
>>> doSomething([[1, 2, 7],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
False

更新2: otherInputs是任何子列表的子集:

def doSomething(myListOfLists, otherInputs):
    s = set(otherInputs)
    return any(s.issubset(item) for item in myListOfLists)
... 
>>> doSomething([[6, 8, 7],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
True
>>> doSomething([[6, 8, 7, 10],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
True
>>> doSomething([[1, 2, 7],[6, 5, 4], [10, 8, 10]], [7, 6, 8])
False

答案 1 :(得分:0)

使用套装

def doSomething(myDictOfLists, otherInputs):

    list1 = []
    ...  # do something here with `otherInputs' 
    ...  # which gives `list1' some values

    # now only append `list1' to `myListOfLists' if it doesn't already exist
    # and if it does exist, remove it
    list1Set = set(list1)
    if list1Set not in myDictOfLists:
        myDictOfLists[list1Set] = list1

    return myDictOfLists

答案 2 :(得分:0)

如果您对给定列表进行排序,然后将其附加到myListOfLists,则可以使用此:

if sorted(list1) in myListOfLists:

答案 3 :(得分:0)

此算法似乎稍微快一些:

l1 = [3, 4, 1, 2, 3]
l2 = [4, 2, 3, 3, 1]
same = True
for i in l1:
    if i not in l2:
        same = False
        break

对于1000000循环,我的计算机需要1.25399184227秒,而

same = sorted(l1) == sorted(l2)

需要1.9238319397秒。