有没有一种方法可以使用列表推导计算某个条件而不是其他元素的按元素分组的频率?

时间:2019-01-17 20:31:44

标签: python list-comprehension

我试图将列表中的元素进行分组以压缩它并使其保持相同的顺序,但前提是它满足某些条件。

说我有一个列表,我使用此列表理解来压缩它:

>> l = [1,1,2,2,3,3,4,4,4,"7","7","7",5,5]
>> [len(list(group)) if not isinstance(key, str) else key for key, group in groupby(l)]

输出:

>> [2, 2, 2, 3, '7', 2]

所需的输出:

>> [2, 2, 2, 3, '7', '7', '7', 2]

因此,我只希望元素的频率(如果它是数字),但是如果它是字符串,则我希望列出每个出现的事件,而不是仅列出一次。

我理解它是因为理解是使用“ groupby(l)”而不是“ l”来创建新列表,但是我有什么选择呢?

3 个答案:

答案 0 :(得分:2)

使用带有chain.from_iterable的生成器表达式:

from itertools import chain, groupby

L = [1,1,2,2,3,3,4,4,4,"7","7","7",5,5]

gen = ([len(list(g))] if not isinstance(k, str) else list(g) for k, g in groupby(L))
res = list(chain.from_iterable(gen))
# [2, 2, 2, 3, '7', '7', '7', 2]
我认为

Cleaner为此定义了一个函数:

from itertools import chain, groupby

def func(args):
    key, grp = args
    lst = list(grp)
    if not isinstance(key, str):
        yield len(lst)
    else:
        yield from lst

res = list(chain.from_iterable(map(func, groupby(L))))
# [2, 2, 2, 3, '7', '7', '7', 2]

答案 1 :(得分:0)

不使用列表理解

from itertools import groupby
l = [1,1,2,2,3,3,4,4,4,"7","7","7",5,5]
out=[]
for key, group in groupby(l):
    if not isinstance(key, str):
        out.append(len(list(group)))
    else:
        out.extend(list(group))

输出[2, 2, 2, 3, '7', '7', '7', 2]

答案 2 :(得分:0)

如果键是字符串,则可以使用嵌套列表理解来逐个遍历分组的项目:

from itertools import groupby
[i for k, g in groupby(l) for i in (list(g) if isinstance(k, str) else (len(list(g)),))]

这将返回:

[2, 2, 2, 3, '7', '7', '7', 2]