簡體   English   中英

檢查列表列表中是否存在列表的最快方法

[英]Fastest way to check if a list is present in a list of lists

我有一份清單

a=[[1,2,3,4,5,6],[7,8,9,10,11,12]]   

什么是檢查是否在任何名單最快的方法a出現在名單另一個列表b ,其中

b=[[5, 9, 25, 31, 33, 36],[7,8,9,10,11,12],[10, 13, 22, 24, 33, 44]]

如果b中存在a中的任何列表,我想將其刪除。 我目前正在使用此代碼:

for each in a:
    for item in b:
        if set(each).issubset(item)
            a.remove(each)

這有效但在處理大型列表時速度很慢,因此想知道是否有更好的方法。 上面的代碼給出了以下結果:

print(a)
[[1, 2, 3, 4, 5, 6]]

我不擔心順序,例如,如果列表中的a[1,2,3,4,5,6]我想,如果存在一個名單將它移走[1,2,3,4,5,6]列表b [1,2,3,4,5,6][3,4,1,6,2,5]等。

使用list comprehensionset

例如:

a=[[1,2,3,4,5,6],[7,8,9,10,11,12]]  
b=[[5, 9, 25, 31, 33, 36],[7,8,9,10,11,12],[10, 13, 22, 24, 33, 44]]

setA = set(map(tuple, a))
setB = set(map(tuple, b))

print([i for i in setA if i not in setB])

輸出:

[(1, 2, 3, 4, 5, 6)]

使用set.difference可以實現功能解決方案:

res = set(map(tuple, a)).difference(set(map(tuple, b)))

[(1, 2, 3, 4, 5, 6)]

說明

  1. 由於list不是hashable類型,我們將子列表轉換為類型tuple ,它們是不可變的和可散列的,例如set(map(tuple, a))
  2. 然后使用set.difference來獲取2個結果集之間的差異。

如果您不關心元素順序和頻率,即將列表視為無序集合,那么可能您的解決方案幾乎是正確的(刪除元素,而迭代相同的列表可能不是最好的想法),具有兩個嚴重的次優。

首先,您目前將每個b的元素轉換為每個元素的一個集合。 我想知道Python編譯器是否可以優化重復的工作,至少你可以嘗試自己做。

接下來,您不需要錯誤地和平方地刪除元素以簡單地過濾它們。

faster_b = [frozenset(x) for x in b]

def not_in_b(list):
    l = frozenset(list)
    for x in faster_b:
        if l <= x: return False
    return True

print(list(filter(not_in_b, a)))

這個可能更快。

$ python3
Python 3.6.5 (default, May 11 2018, 04:00:52) 
[GCC 8.1.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a=[[1,2,3,4,5,6],[7,8,9,10,11,12]]
>>> b=[[5, 9, 25, 31, 33, 36],[7,8,9,10,11,12],[10, 13, 22, 24, 33, 44]]
>>> faster_b = [frozenset(x) for x in b]
>>> 
>>> def not_in_b(list):
...     l = frozenset(list)
...     for x in faster_b:
...         if l <= x: return False
...     return True
... 
>>> print(list(filter(not_in_b, a)))
[[1, 2, 3, 4, 5, 6]]
>>> a=[[1, 1, 2, 3]]
>>> b=[[7, 3, 2, 1], [4, 5, 6]]
>>> faster_b = [frozenset(x) for x in b]
>>> print(list(filter(not_in_b, a)))
[]
>>> a=[[1, 1, 2, 3], [42, 5, 6]]
>>> print(list(filter(not_in_b, a)))
[[42, 5, 6]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM