Длина выполнения Кодирование кода
Я очень новичок в кодировании и выбрал 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