2014-10-29 71 views
-4

我有一個元素序列,每個元素都與一個元組中的權重w(一個正整數)相關聯。創建包含每個元素e_iw_i實例的序列或列表有什麼好方法(最好是基於迭代器的)?創建列表元素的多個副本

weighted = [ ("a", 3), ("b", 1), ("c", 4) ] 

unrolled = [ "a", "a", "a", "b", "c", "c", "c", "c" ] 
+0

我能抽出點的另一種方式,但我很好奇downvoters認爲這個問題是錯誤的。它已經有了一些很好的答案。 – alexis 2014-10-29 12:30:43

+0

我沒有投票,但你沒有顯示任何嘗試自己解決你的問題。 – 2014-10-29 13:08:22

回答

2

使用列表中理解嵌套循環:

unrolled = [c for c, count in weighted for _ in range(count)] 

如果您正在使用Python 2,你可以使用xrange()代替。

如果你喜歡itertools,您可以使用itertools.chain.from_iterable(),使之成爲一個懶惰的迭代這樣的:

from itertools import chain 

chain.from_iterable([c] * count for c, count in weighted) 

演示:

>>> weighted = [ ("a", 3), ("b", 1), ("c", 4) ] 
>>> [c for c, count in weighted for _ in range(count)] 
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'] 
>>> from itertools import chain 
>>> list(chain.from_iterable([c] * count for c, count in weighted)) 
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'] 

我用list()打開chain迭代器放回序列。

+0

很快! :-) – alexis 2014-10-29 12:02:26

+0

呵呵,在回答之前不知道強制性等待。不錯,除了第一次使用的用戶可能會在15分鐘結束之前永遠消失... – alexis 2014-10-29 12:03:58

0

該方法基本上使用生成器表達式和join創建單個字符串,然後將該字符串轉換爲list

weighted = [ ("a", 3), ("b", 1), ("c", 4) ] 
unrolled = list(''.join([letter*count for letter,count in weighted])) 

>>> unrolled 
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'] 
+0

對不起,但這讓我感到非常迂迴,並且限於(1)個字符串(2)一個字母。有了這麼多的選擇,爲什麼字符串乘法? – alexis 2014-10-29 12:28:31

+0

字符串恰好適合用例。有任何序列的模擬,但是,例如[3] * 3是[3,3,3],所以您可以使用這種方式再次使用序列。在這種情況下,您可以使用'chain.from_iterable'而不是'join'。 – CoryKramer 2014-10-29 12:33:40

1

Counter有這種邏輯建立在假設的順序並不重要

>>> weighted = [ ("a", 3), ("b", 1), ("c", 4) ] 
>>> from collections import Counter 
>>> c = Counter(dict(weighted)) 
>>> list(c.elements()) 
['a', 'a', 'a', 'c', 'c', 'c', 'c', 'b'] 

與itertools(很多人)

>>> from itertools import chain, repeat, starmap 
>>> list(chain.from_iterable(starmap(repeat, weighted))) 
['a', 'a', 'a', 'b', 'c', 'c', 'c', 'c'] 
+0

不錯!事實上,秩序並不重要。 (我的意思是'計數器'解決方案。當有更簡單的解決方案時,'itertools'只是太多了。 – alexis 2014-10-29 12:26:34

+1

@alexis,我同意。我只是把它放在那裏,因爲我從來沒有在任何地方使用'starmap' – 2014-10-29 20:49:55

+0

我喜歡'Counter'方法,但我決定接受理解,因爲它依賴於Python的更加着名的特性。 – alexis 2014-10-30 09:05:22