2016-08-31 155 views
0

給定一個列表l和列表元素的所有組合是否可以在遍歷所有組合時刪除包含x的任何組合,以便在刪除它之後的迭代中從不考慮包含x的組合?迭代時從itertools.combinations中刪除元素?

for a, b in itertools.combinations(l, 2): 
    if some_function(a,b): 
     remove_any_tup_with_a_or_b(a, b) 

我的目錄l是相當大的,所以我不希望保留的組合在內存中。

+0

@ PM2Ring:我認爲關於「我不想把組合保存在內存中」的評論意味着創建所有組合的「列表」(或其他數據結構)的簡單方法,所以你可以在識別後立即從「列表」中刪除「壞」組合,這將不合適。大多數人甚至知道「itertools」意識到發生器的工作原理(避免前期內存成本)。 – ShadowRanger

+0

@ShadowRanger:哦,好的。 –

回答

2

完成此操作的便宜技巧是使用排除值的動態更新set進行不相交測試,但實際上並不會避免生成您希望排除的組合,因此它不是主要的性能優勢(儘管filter ING使用C內置函數一樣isdisjoint會比Python的水平更快if檢查與一般continue語句,通過推動filter工作到C層):

from future_builtins import filter # Only on Py2, for generator based filter 
import itertools 

blacklist = set() 
for a, b in filter(blacklist.isdisjoint, itertools.combinations(l, 2)): 
    if some_function(a,b): 
     blacklist.update((a, b)) 
0

如果您要刪除包含所有元組號碼x從列表中考慮到您從集合itertools.combinations([i for i in range(1,len(l)], 2)itertools.combinations(l, 2)存在一對一映射(數學地說),其中不包含包含的數字x

實施例:

itertools.combinations([1,2,3,4], 2)從該組的所有組合中的不包含數字1是由[(2, 3), (2, 4), (3, 4)]給出。請注意,此列表中元素的數量等於列表itertools.combinations([1,2,3], 2)=[(1, 2), (1, 3), (2, 3)]中組合元素的數量。

由於訂單組合無關緊要,您可以在[(1, 2), (1, 3), (2, 3)]中映射1到4以獲得[(1, 2), (1, 3), (2, 3)]=[(4, 2), (4, 3), (2, 3)]=[(2, 4), (3, 4), (2, 3)]=[(2, 3), (2, 4), (3, 4)]