Длина выполнения Кодирование кода

Я очень новичок в кодировании и выбрал Python в качестве моего первого языка программирования. Я работаю над упражнением под названием Run Length Encoding. После некоторых поисков я нашел решение, но мне трудно понять код. Может кто-нибудь взломать этот код и объяснить простыми словами. Благодарю вас.

string = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB'
x=''.join(['{}{}'.format(k, sum(1 for _ in g)) for k, g in groupby(string)])

2 ответа

Решение

Первое, что нужно сделать, это разбить выражение на более мелкие:

bits = ['{}{}'.format(k, sum(1 for _ in g)) for k, g in groupby(string)]
x=''.join(bits)

Второй простой: у нас есть список битов, каждый из которых является строкой, и мы просто объединяем их в одну большую строку.

Первый - это понимание списка. Каждое понимание списка может быть переписано как for заявление вокруг append Итак, давайте сделаем это:

bits = []
for k, g in groupby(string):
    bits.append('{}{}'.format(k, sum(1 for _ in g)))

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

for k, g in groupby(string):
    print(k, list(g))

Это дает вам:

W ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W']
B ['B']
W ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W']
B ['B', 'B', 'B']
W ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W']
B ['B']

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


Теперь давайте разберем внутреннее утверждение:

bits.append('{}{}'.format(k, sum(1 for _ in g)))

на части:

count = sum(1 for _ in g)
bit = '{}{}'.format(k, count)
bits.append(bit)

Последние две строки, надеюсь, очевидны. Так что это просто оставляет нас с первым.


Мы звоним sum на генераторе выражения. Выражения генератора похожи на списки, но ленивы, и нам здесь нет дела до лени, поэтому мы можем разбить их так же, как мы делали выше:

things = []
for _ in g:
    things.append(1)
count = sum(things)

Так что теперь должно быть очевидно, что sum(1 for _ in g) делает: это просто количество вещей в g, На самом деле, это как звонить len(g) за исключением того, что он работает для произвольных итераций, включая ленивые итераторы, а не только последовательности.

Это идиоматический способ подсчета, возможно, ленивых итераций, но мы могли бы заменить его (ценой производительности) на:

count = len(list(g))

Итак, собираем все вместе:

  • использование groupby чтобы преобразовать строку в группу групп, каждая из которых повторяется снова и снова.
  • Для каждого:
    • Посчитайте длину этой группы.
    • Сделать строку как 'W12' используя ключ 'W' и тот факт, что группа W имеет 12 членов.
    • Добавьте это в список.
  • Возьми этот список ['W12', 'B1', 'W12', 'B3', 'W24', 'B1'] и присоединить его в строку 'W12B1W12B3W24B1',

Рассматривать s = 'WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB',
Ваш код эквивалентен:

x=''.join(['{}{}'.format(k, len(list(g))) for k, g in groupby(s)])

x=''.join([str(k) + str(len(list(g))) for k, g in groupby(s)])

l=[]
for k, g in groupby(s):
    l.append(str(k) + str(len(list(g))))

x= ""
for s in l:
    x += s

Из документации " groupby создает итератор, который возвращает последовательные ключи и группы из итерируемого".

Это проще понять на примере.

print(*[(k,list(g)) for k, g in groupby(s)], sep="\n")

выходы:

('W', ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W'])
('B', ['B'])
('W', ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W'])
('B', ['B', 'B', 'B'])
('W', ['W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W', 'W'])
('B', ['B'])

На практике каждый элемент в итераторе, возвращаемый groupby, является char c с итератором в список всех последовательных chars c,

В своем коде вы сначала создаете список со всеми парами (c, число последовательных раз c появляется):

x1 = ['{}{}'.format(k, len(list(g))) for k, g in groupby(s)]
# ['W12', 'B1', 'W12', 'B3', 'W24', 'B1']

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

x2 = "".join(x1)
# W12B1W12B3W24B1
Другие вопросы по тегам