Использование map() для возврата списка в Python 3.x
Проблема:
Я пытаюсь преобразовать список в шестнадцатеричный формат и затем использовать этот список в других частях кода. В Python 2.6 это было просто:
A: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
Однако в Python 3.1 вышеуказанный код возвращает объект типа map
:
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Как мне вернуть преобразованный список (как в A) в Python 3.x?
Кроме того, существует ли лучший способ сделать это? Мой исходный список содержит около 45 элементов, и я хотел бы преобразовать их в шестнадцатеричный формат.
5 ответ(ов)
В Python 3+ многие функции, которые работают с итерируемыми объектами, возвращают сами итераторы. Это зачастую позволяет экономить память и может ускорять выполнение кода.
Если вам нужно просто перебрать элементы, в вашем случае нет необходимости преобразовывать объект в список, так как вы можете итерировать по объекту map
напрямую. Например:
# Выводит "ABCD"
for ch in map(chr, [65, 66, 67, 68]):
print(ch)
Таким образом, лучше писать код так, чтобы воспользоваться преимуществами итераторов, что приведет к более эффективному использованию ресурсов.
Функция map
, возвращающая список, имеет преимущество в том, что экономит время на набор текста, особенно в интерактивных сессиях. Вы можете определить функцию lmap
(по аналогии с imap
из Python 2), которая будет возвращать список:
lmap = lambda func, *iterable: list(map(func, *iterable))
Таким образом, вызов lmap
вместо map
позволит вам сократить время на написание: lmap(str, x)
короче на 5 символов (на 30% в данном случае), чем list(map(str, x))
, и определенно короче, чем [str(v) for v in x]
. Вы можете создать аналогичные функции для filter
.
Был комментарий к исходному вопросу:
Я бы предложил переименовать в "Как сделать так, чтобы map() возвращала список в Python 3.*", так как это касается всех версий Python 3. Есть ли способ сделать это? – meawoppl 24 янв в 17:58
Это возможно, но это очень плохая идея. Только для развлечения, вот как вы могли бы (но не должны) это сделать:
__global_map = map # сохраняем ссылку на оригинальный map
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # использование "map" здесь вызовет бесконечную рекурсию
map = lmap
x = [1, 2, 3]
map(str, x) # проверка
map = __global_map # восстанавливаем оригинальный map и больше так не делаем
map(str, x) # итератор
Хотя такая реализация и возможна, лучше избегать изменений встроенных функций, чтобы сохранить чистоту и предсказуемость кода.
Функция map()
в Python позволяет применить заданную функцию к каждому элементу из одного или нескольких итерируемых объектов. В вашем случае:
list(map(chr, [66, 53, 0, 94]))
здесь map()
создает итератор, который применяет функцию chr
к каждому элементу списка [66, 53, 0, 94]
. Это означает, что next()
этого итератора будет извлекать по одному элементу из списка и передавать его в функцию chr
, которая возвращает символ, соответствующий переданному числовому коду в таблице ASCII.
Следует отметить, что функция map()
вернет итератор, и чтобы получить результаты в виде списка, вам нужно обернуть его в list()
, как в вашем примере. Итогом будет список символов:
['B', '5', '\x00', '^']
Так, list()
просто преобразует результирующий итератор в список. Вы также можете использовать списковые включения, чтобы получить тот же результат:
[chr(x) for x in [66, 53, 0, 94]]
Этот подход может быть более читаемым в некоторых случаях. В общем, map()
полезен для применения одной функции ко многим элементам сразу.
Вы можете использовать генераторы списков в Python и функцию map
для создания нового списка. В вашем примере код выглядит следующим образом:
chi = [x for x in map(chr, [66, 53, 0, 94])]
Здесь map
применяется к функции chr
, которая преобразует числовые значения (в данном случае ASCII-коды) в соответствующие символы. В результате map
возвращает итератор, который вы затем оборачиваете в генератор списков, чтобы получить финальный список символов.
Вы можете реализовать тот же результат без генератора списков, просто используя list(map(...))
:
chi = list(map(chr, [66, 53, 0, 94]))
Оба варианта дадут вам один и тот же список символов. В этом случае chi
будет равно ['B', '5', '\x00', '^']
.
Вы можете попробовать получить список из объекта map
, просто перебрав каждый элемент в объекте и сохранив его в отдельной переменной.
a = map(chr, [66, 53, 0, 94])
b = [item for item in a]
print(b)
>>> ['B', '5', '\x00', '^']
В этом примере map
применяет функцию chr
к каждому элементу списка [66, 53, 0, 94]
, а затем с помощью генератора списков мы собираем результаты в новый список b
.
Как вернуть ключи словаря в виде списка в Python?
Как получить последний элемент списка?
Как клонировать список, чтобы он не изменялся неожиданно после присваивания?
Как отсортировать список/кортеж списков/кортежей по элементу на заданном индексе
Ошибка: "'dict' объект не имеет метода 'iteritems'"