簡體   English   中英

獲得有序的獨特項目列表的最佳/最pythonic方式

[英]Best / most pythonic way to get an ordered list of unique items

我有一個或多個(不可變的,可散列的)對象的無序序列,可能有重復項,我想得到所有這些對象的排序序列,沒有重復。

現在我正在使用一個集合來快速收集所有丟棄重復項的元素,將其轉換為列表然后對其進行排序:

result = set()
for s in sequences:
    result = result.union(s)
result = list(result)
result.sort()
return result

它有效,但我不會稱之為“漂亮”。 有沒有更好的辦法?

這應該工作:

sorted(set(itertools.chain.from_iterable(sequences)))

我很喜歡你的代碼。 它簡單易懂。

我們可以通過鏈接list()來縮短它一點點:

result = set()
for s in sequences:
    result = result.union(s)
return sorted(result)

我真的不想嘗試將其燒掉,但你可以用reduce()來做到這一點:

result = reduce(lambda s, x: s.union(x), sequences, set())
return sorted(result)

就個人而言,我認為這比上面的內容更難理解,但沉浸在函數式編程中的人可能更喜歡它。

編輯:@agf在這個reduce()要比我好多了。 從下面的評論:

return sorted(reduce(set().union, sequences))

我不知道這會起作用。 如果我正確理解它是如何工作的,我們給reduce()一個callable,它實際上是一個set()一個實例上的方法函數(為了討論起見,將其稱為x ,但請注意,我並不是說Python會將名稱x與此對象綁定)。 然后reduce()將從sequences的前兩個迭代中提供此函數,返回x ,即我們正在使用其方法函數的實例。 然后reduce()將重復調用.union()方法,並要求它從sequences中獲取x和下一個iterable的並集。 由於.union()方法可能足夠聰明,可以注意到它被要求使用自己的實例獲取聯合而不需要做任何工作,因此調用x.union(x, some_iterable)速度應該同樣快。至於只調用x.union(some_iterable) 最后, reduce()將返回x ,我們有我們想要的集合。

這對我的個人品味來說有點棘手。 我不得不考慮這一點來理解它,而itertools.chain()解決方案立即對我有意義。

編輯:@agf使它不那么棘手:

return sorted(reduce(set.union, sequences, set()))

這樣做要簡單易懂! 如果我們再次通過名稱x調用set()返回的實例(就像上面一樣,理解我並不是聲稱Python會將名稱x與此實例綁定); 如果我們使用名稱n來引用sequences每個“下一個”值; 然后reduce()將重復調用set.union(x, n) 當然,這與x.union(n)完全相同。 恕我直言,如果你想要一個reduce()解決方案,這是最好的解決方案。

-

如果你想要快速,請問自己:我們有什么方法可以將itertools應用於此嗎? 有一個很好的方法:

from itertools import chain
return sorted(set(chain(*sequences)))

*sequences調用的itertools.chain()用於將列表列表“展平”為單個可迭代。 這有點棘手,但只是一點點,這是一個常見的習語。

編輯:正如@Jbernardo在最流行的答案中所寫,並且正如@agf在注釋中所觀察到的, itertools.chain()返回一個具有.from_iterable()方法的對象,文檔說它會懶惰地評估迭代。 *表示法強制構建一個列表,如果可迭代是一個長序列,它可能會占用大量內存。 實際上,你可以擁有一個永無止境的生成器,並且使用itertools.chain().from_iterable() ,只要你想運行你的程序就可以從中提取值,而*表示法只會運行記不清。

正如@Jbernardo所寫:

sorted(set(itertools.chain.from_iterable(sequences)))

這是最好的答案,我已經對它進行了投票。

暫無
暫無

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

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