2017-04-09 68 views
2

這一直給我一些麻煩一段時間,也許我有隧道視覺。給定一個整數列表,生成一個新的列表,其中每組相鄰的副本已經變成一個元組。使用列表理解,元組和itertools.groupby

例如,給出的列表:[1, 2, 3, 3, 4, 5, 5, 5, 6]

生成的列表包含:[1, 2, (3, 3), 4, (5, 5, 5), 6]

我想實現這個用list理解。

numbers = [1, 2, 3, 3, 4, 5, 5, 5, 6] 

it = itertools.groupby(numbers) 
numbers = [tuple(group) if len(tuple(group)) > 1 else key for key, group in it] 

結果我很期待:

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

結果我得到:

[1, 2,(), 4,(), 6]

插入的元組是空的,顯然 - 但在同時他們不是,因爲他們必須有不止一個元素才能插入到第一個位置。這是怎麼回事?我是python的新手,甚至在耗盡了所有能夠想到的關鍵字之後,我仍然無法在線找到類似的問題。我確定這很簡單,我只是看不到它。任何幫助表示讚賞。

回答

0

的問題是,該組變量是隻能使用一次迭代的迭代器。耗盡後顯得空虛。您需要臨時存儲中間組。去爲itzmeontv建議使用嵌套發電機/ comprehesions,或使用映射函數的一種方法:

def make_group(group): 
    group = tuple(group) 
    if len(group) == 1: 
    return group[0] 
    return group 

numbers = [make_group(group) for key, group in itertools.group_by(numbers)] 
+0

謝謝塔瑪斯!我已經接受你的答案,因爲你提供了一個解釋,解決了我的問題。 –

3

如果你想要做list comprehension

>>>l = [1, 2, 3, 3, 4, 5, 5, 5, 6] 
>>>[k[0] if len(k) == 1 else tuple(k) for k in [list(j) for i,j in itertools.groupby(l)]] 
[1, 2, (3, 3), 4, (5, 5, 5), 6] 
+0

謝謝@itzmeontv! –

1

你可以試試這個

a = [1, 2, 3, 3, 4, 5, 5, 5, 6] 
[(i,)*a.count(i) if a.count(i)>1 else i for i in set(a)] 

輸出:

[1, 2, (3, 3), 4, (5, 5, 5), 6] 
+0

我不知道OP是否需要它們,但是在大多數情況下,您的答案不會返回數字(僅用於小數字),(除了具有非最佳時間複雜度)。 –