簡體   English   中英

兩個非連續項目的組合

[英]Combinations of two non-consecutive items

給定一個列表,我如何獲得兩個非連續項之間的所有組合?

例如,對於輸入[1, 2, 3, 4, 5] ,我如何得到輸出[(1,3), (1,4), (1,5), (2,4), (2,5), (3,5)]

我對(1,2)(2,3)(3,4)(4,5)不感興趣,因為它們在列表中是連續的(即彼此相鄰),但我還是其他一切感興趣。

在Python中最常用的方法是什么?

一個簡單的列表理解:

>>> lst = [1, 2, 3, 4, 5]
>>> [(a, b) for i, a in enumerate(lst) for b in lst[i+2:]]
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

這是一種相當“慣用”的方式,不使用任何模塊,這比其他一些實現更有效,因為每次使用循環都會被使用 - 沒有被拒絕的可能性。

r = [1, 2, 3, 4, 5]
c = [(r[i], r[j]) for i in range(len(r)-2) for j in range(i+2, len(r))]
print(c)

這給了

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

它不是完全慣用的,因為它循環於索引而不是值,但是你對列表中的位置而不是值的限制使得這非常必要。 如果需要生成器而不是列表,請用括號替換外括號。

如果您對列表中包含非連續數字的組合感興趣:

from itertools import combinations

lst = [1, 2, 3, 4, 5]
list(filter(lambda x: lst.index(x[1]) - lst.index(x[0]) > 1, combinations(lst,2)))

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

這比較了給定組合中兩個數字的指數,並確保它們的指數差異大於1。

我希望它有所幫助。

這是r-長度組合避免連續元素的通用解決方案。 它獲得適當縮短列表的所有索引組合 ,然后展開每個組合的索引。 例如,對於r = 3,任何組合(x,y,z)變成使用的索引x + 0,y + 1,z + 2。

from itertools import combinations

def non_consecutive_combinations(lst, r):
    return [tuple(lst[j+i] for i, j in enumerate(combi))
            for combi in combinations(range(len(lst)-r+1), r)]

r = 2的演示:

>>> non_consecutive_combinations([1, 2, 3, 4, 5], 2)
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

r = 3的演示:

>>> non_consecutive_combinations([1, 2, 3, 4, 5, 6, 7], 3)
[(1, 3, 5), (1, 3, 6), (1, 3, 7), (1, 4, 6), (1, 4, 7), (1, 5, 7), (2, 4, 6), (2, 4, 7), (2, 5, 7), (3, 5, 7)]

僅適用於對的簡化版本:

>>> [(lst[i], lst[j+1]) for i, j in combinations(range(len(lst)-1), 2)]
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

暫無
暫無

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

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