我有一個包含嵌套列表的列表,我需要知道在這些嵌套列表中搜索的最有效方法。在python中搜索嵌套列表的最有效方法是什麼?
例如,如果我有
[['a','b','c'],
['d','e','f']]
,我要上面搜索整個列表,什麼是要找到「d」的最有效方法是什麼?
我有一個包含嵌套列表的列表,我需要知道在這些嵌套列表中搜索的最有效方法。在python中搜索嵌套列表的最有效方法是什麼?
例如,如果我有
[['a','b','c'],
['d','e','f']]
,我要上面搜索整個列表,什麼是要找到「d」的最有效方法是什麼?
mylist = [['a','b','c'],['d','e','f']]
'd' in [j for i in mylist for j in i]
產量:
True
這也可以用發生器完成(如@AshwiniC所示haudhary)根據下面的評論
更新:
下面是相同的列表理解,但是使用更具描述性的變量名:
'd' in [elem for sublist in mylist for elem in sublist]
列表理解部分的循環結構相當於
for sublist in mylist:
for elem in sublist
並生成一個列表,其中'd'可以用in
運營商。
用生成器表達式,這裏的整個列表將不會被橫移爲發電機產生的結果逐一:給
>>> lis = [['a','b','c'],['d','e','f']]
>>> 'd' in (y for x in lis for y in x)
True
>>> gen = (y for x in lis for y in x)
>>> 'd' in gen
True
>>> list(gen)
['e', 'f']
~$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]" "'d' in (y for x in lis for y in x)"
100000 loops, best of 3: 2.96 usec per loop
~$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]" "'d' in [y for x in lis for y in x]"
100000 loops, best of 3: 7.4 usec per loop
如果你的陣列始終排序爲你展示,讓a[i][j] <= a[i][j+1]
和a[i][-1] <= a[i+1][0]
(一個數組的最後一個元素始終小於或等於下一個數組中的第一個元素),那麼你就可以消除很多的比較通過執行類似:
a = # your big array
previous = None
for subarray in a:
# In this case, since the subarrays are sorted, we know it's not in
# the current subarray, and must be in the previous one
if a[0] > theValue:
break
# Otherwise, we keep track of the last array we looked at
else:
previous = subarray
return (theValue in previous) if previous else False
,如果你有很多的陣列,他們都有很多的元素,雖然這種優化的僅是值得的。
謝謝你 - 我沒有考慮過對它們進行排序,但它們會經常使用,所以我會考慮排序 – fdsa 2012-08-15 03:39:51
沒問題 - 我不知道你會得到多少數據或者你的確切用例是的,但是如果你確實有很多數據,可能需要查看python的[collections](http://docs.python.org/library/collections.html)模塊,該模塊具有適合特定應用的高性能數據結構任務。 – 2012-08-15 03:49:35
它們總是被排序,你會更好地使用'bisect'模塊 – 2012-08-15 04:44:17
>>> lis=[['a','b','c'],['d','e','f']]
>>> any('d' in x for x in lis)
True
使用any
$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]" "any('d' in x for x in lis)"
1000000 loops, best of 3: 1.32 usec per loop
發生器表達
$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]" "'d' in (y for x in lis for y in x)"
100000 loops, best of 3: 1.56 usec per loop
列表理解
發生器表達$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]" "'d' in [y for x in lis for y in x]"
100000 loops, best of 3: 3.23 usec per loop
如果項目接近結束或根本不存在,該怎麼辦? any
比列表理解更快
$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]"
"'NOT THERE' in [y for x in lis for y in x]"
100000 loops, best of 3: 4.4 usec per loop
$ python -m timeit -s "lis=[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]"
"any('NOT THERE' in x for x in lis)"
100000 loops, best of 3: 3.06 usec per loop
也許如果列表長1000倍?any
仍然較快
$ python -m timeit -s "lis=1000*[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]"
"'NOT THERE' in [y for x in lis for y in x]"
100 loops, best of 3: 3.74 msec per loop
$ python -m timeit -s "lis=1000*[['a','b','c'],['d','e','f'],[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15],[16,17,18]]"
"any('NOT THERE' in x for x in lis)"
100 loops, best of 3: 2.48 msec per loop
我們知道,發電機需要一段時間才能成立,因此對於LC贏得了最好的機會是在很短的名單
$ python -m timeit -s "lis=[['a','b','c']]"
"any('c' in x for x in lis)"
1000000 loops, best of 3: 1.12 usec per loop
$ python -m timeit -s "lis=[['a','b','c']]"
"'c' in [y for x in lis for y in x]"
1000000 loops, best of 3: 0.611 usec per loop
而且any
使用較少的內存也
我會謹慎地基於搜索「d'」(即相對接近列表前面的內容)來概括這一點。如果你看看@Ashwini和我的討論(在他的回答下),你會發現列表中「目標」的選擇有很大的不同。在我們的試驗中,LC在中間和末端擊中發電機。如果目標靠近前方,發電機「贏得」。我認爲最終它完全依賴於特定的數據集和追求的目標。 – Levon 2012-08-15 04:53:20
@Levon,我非常清楚這種權衡。然而在這種情況下,即使物品完全不存在,「任何」仍然比LC快。 – 2012-08-15 04:58:57
我並不是故意暗示你不是......在使用「any」之前,我一直沒有提到它,所以這是我爲了將來的使用而記住的事情。 – Levon 2012-08-15 05:01:14
只要我能理解發生了什麼,你能澄清我和我是什麼? – fdsa 2012-08-15 03:34:42
@fdsa我會通過添加一個「詳細」版本(更多描述性變量名稱)來更新我的答案 – Levon 2012-08-15 03:36:59
感謝您抽出時間,我感謝它 – fdsa 2012-08-15 03:38:50