Есть ли способ использовать понимание списка для подсчета частоты группирования элементов для определенного условия, но не для других элементов? - PullRequest
0 голосов
/ 17 января 2019

Я пытаюсь сгруппировать элементы в списке, чтобы сжать его и сохранить в том же порядке, но только если он удовлетворяет определенным условиям.

Скажем, у меня есть список, и я сокращаю его, используя это понимание списка:

>> 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 голосов
/ 17 января 2019

Не используется списочное понимание

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]

0 голосов
/ 17 января 2019

Вы можете использовать понимание вложенного списка, чтобы перебирать сгруппированные элементы индивидуально, если ключ является строкой:

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]
0 голосов
/ 17 января 2019

Использование выражения генератора с 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]

Очиститель, на мой взгляд, определяет функцию для этого:

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]
...