Я пытаюсь понять код Хаффмана, написанный на python под «кодом Розетты». Ниже приведена небольшая часть кода.
def encode(symb2freq):
heap = [[wt, [sym, ""]] for sym, wt in symb2freq.items()] #What does this do?
Я предполагаю, что переменная heap
является списком. Но что такое wt
и sym
?
4 ответа
sym2freq
- это словарь с ключами, некоторыми символами и их значениями частоты символа. Например, если у вас есть строка «aaabacba», словарь будет выглядеть следующим образом
sym2freq = {'a': 5, 'b': 2, 'c': 1}
Это потому, что у нас есть 5 раз буква а, 2 раза буква b и 1 раз буква c.
У словарей есть метод items()
, который будет возвращать кортеж каждого ключа с соответствующим значением. В нашем случае он вернется
>>> sym2freq.items()
(('a', 5), ('b', 2), ('c', 1))
for sym, wt in symb2freq.items()
часть списка понимания просто распаковывается. Каждый раз, когда мы выбираем один из наших кортежей сверху, мы назначаем первый объект переменной sym
, а второй - переменной wt
. Названия sym и wt были выбраны исключительно для отражения значений, которые представляют, то есть символа и веса (частоты).
>>> sym, wt = ('a', 5)
>>> print sym
'a'
>>> print wt
5
И так как понимание списка создаст списки структуры [wt, [sym, ""]]
, вы получите список
>>> encode(sym2freq)
[[5, ['a', '']], [2, ['b', '']], [1, ['c', '']]]
Причина, по которой мы переходим от словаря частот символов к структуре, подобной списку heap
, заключается в том, что мы можем сортировать символы по их частотам, что, как вы изучаете, является частью построения дерева Хаффмана.
Это интересная проблема. Представьте себе словарь из пяти букв, где ключ - это буква, а значение - частота:
a = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}
Затем сопоставьте его так, чтобы он представлял собой список списков с частотой и список, начинающийся с буквы в переменной кучи, например:
[[1, ['a', '']], [2, ['b', '']], [3, ['c', '']], [4, ['d', '']], [5, ['e', '']]]
Затем, когда вы его накапливаете, вы получаете:
[[1, ['a', '']],
[3, ['c', '']],
[2, ['b', '']],
[5, ['e', '']],
[4, ['d', '']]]
Просто поработайте шаг за шагом с действительным словарем для кодирования, подобным приведенному на странице википедии, и вы сможете увидеть, что делает каждый шаг. Или используйте тривиальный пример, чтобы начать как тот, который я дал, и постепенно увеличивайте количество элементов, пока вы не работаете с реальным документом.
Код Розетты выполняет итерацию в куче и добавляет цифры к пустой строке, которую вы видите после буквы, основываясь на частоте, до тех пор, пока каждая буква не будет преобразована в двоичную интерпретацию. Итак, в конце концов вы получите что-то вроде этого:
[['e', '101'],
['d', '010'],
['c', '1001'],
['b', '1100'],
['a', '1101']]
Где самые частые буквы требуют наименьшего количества бит.
Это понимание списка. Это говорит
- Возьмите предметы из
symb2freq
и начните их перебирать. - Получите первый элемент в
symb2freq
и распакуйте его в переменныеsym
иwt
. - Теперь добавьте
[wt, [sym, ""]]
в список - Сделайте это для каждого предмета
- Теперь поместите список в переменную
heap
Например, [bar(x) for x in foo]
создает список, который применяет bar(x)
к каждому значению в списке.
Sym - символ, а wt - вес.
https://en.wikipedia.org/wiki/Huffman_coding
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.