[英]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.