2017-04-09 43 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是否需要它们,但是在大多数情况下,您的答案不会返回数字(仅用于小数字),(除了具有非最佳时间复杂度)。 –