你可以在索引2.使用itertools.groupby
到組基於價值的元組然後爲每個組可以使用random.choice
選擇一個元組:
>>> from itertools import groupby
>>> import random
>>> l = [(0, 4, 1.0), (1, 4, 1.0), (3, 4, 1.0), (0, 3, 2.0), (1, 3, 2.0), (0, 2, 3.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, float('inf'))]
>>> [random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2])]
[(1, 4, 1.0), (1, 3, 2.0), (1, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)]
在上面groupby
回報可迭代(key, group)
元組,其中關鍵是值通過第二個參數返回給groupby
和組是可迭代的元素的組內:
>>> [(k, tuple(g)) for k, g in groupby(l, key=lambda x: x[2])]
[(1.0, ((0, 4, 1.0), (1, 4, 1.0), (3, 4, 1.0))), (2.0, ((0, 3, 2.0), (1, 3, 2.0))), (3.0, ((0, 2, 3.0), (1, 2, 3.0))), (4.0, ((2, 4, 4.0),)), (5.0, ((2, 3, 5.0),)), (inf, ((0, 1, inf),))]
因爲我們不需要的關鍵,我們可以放棄它並轉換組到序列random.choice
預計:
>>> [random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2])]
[(1, 4, 1.0), (1, 3, 2.0), (0, 2, 3.0), (2, 4, 4.0), (2, 3, 5.0), (0, 1, inf)]
注意,上述預期與相同值元組索引2是在輸入彼此相鄰。如果不是這種情況,您可以在將原始列表傳遞到groupby
之前對其進行排序。
更新如果你只是想要的結果,你可以用它代替列表理解發電機表達,並從那裏獲取值出與islice
的三個第一值:
>>> from itertools import islice
>>> gen = (random.choice(tuple(g)) for _, g in groupby(l, key=lambda x: x[2]))
>>> list(islice(gen, 3))
[(0, 4, 1.0), (1, 3, 2.0), (0, 2, 3.0)]
都與相同的值索引2元組在輸入中彼此相鄰?如果不是輸出的正確順序是什麼? – niemmi
我可以對它們進行排序,就像它們高於 –