Вопрос

Я пытаюсь преобразовать список в шестнадцатеричный формат, а затем использовать этот список в другом месте.В 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?

В качестве альтернативы, есть ли лучший способ сделать это?Мой первоначальный объект list содержит около 45 элементов, и я хотел бы преобразовать их в шестнадцатеричный формат.

Это было полезно?

Решение

Сделай это:

list(map(chr,[66,53,0,94]))

В Python 3+ многие процессы, которые повторяют iterables, сами возвращают итераторы.В большинстве случаев это приводит к экономии памяти и должно ускорить работу.

Если все, что вы собираетесь сделать, это в конечном итоге выполнить итерацию по этому списку, нет необходимости даже преобразовывать его в список, потому что вы все равно можете выполнить итерацию по map объект, подобный этому:

# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
    print(ch)

Другие советы

Почему ты этого не делаешь:

[chr(x) for x in [66,53,0,94]]

Это называется пониманием списка.Вы можете найти много информации в Google, но вот ссылка на документацию Python (2.6) по пониманию списков.Возможно, вас больше заинтересует документация Python 3, хотя.

Новое и аккуратное в Python 3.5:

[*map(chr, [66, 53, 0, 94])]

Благодаря Дополнительные обобщения Распаковки

Обновить

Всегда ища более короткие пути, я обнаружил, что этот тоже работает:

*map(chr, [66, 53, 0, 94]),

Распаковка работает и в кортежах.Обратите внимание на запятую в конце.Это делает его кортежем из 1 элемента.То есть, это эквивалентно (*map(chr, [66, 53, 0, 94]),)

Это короче всего на один символ по сравнению с версией со списком-скобками, но, на мой взгляд, лучше писать, потому что вы начинаете прямо со звездочки - синтаксиса расширения, поэтому я чувствую, что это мягче на уме.:)

Преимущество функции карты, возвращающей список, заключается в экономии ввода, особенно во время интерактивных сеансов.Вы можете определить lmap функция (по аналогии с python2's imap), который возвращает список:

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 слишком.

Там был комментарий к первоначальному вопросу:

Я бы предложил переименовать в Getting map() для возврата списка в Python 3. * поскольку это применимо ко всем версиям Python3.Есть ли способ сделать это?– meawoppl 24 января в 17:58

IT является это возможно сделать, но это очень плохая идея.Просто для развлечения, вот как вы можете (но не следует) сделай это:

__global_map = map #keep reference to the original map
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # using "map" here will cause infinite recursion
map = lmap
x = [1, 2, 3]
map(str, x) #test
map = __global_map #restore the original map and don't do that again
map(str, x) #iterator

Я не знаком с Python 3.1, но сработает ли это?

[chr(x) for x in [66, 53, 0, 94]]

Преобразование мой старый комментарий для лучшей видимости:Для "лучшего способа сделать это" без map в целом, если известно, что ваши входные данные являются порядковыми числами ASCII, как правило, преобразование в bytes и расшифровывать, а-ля bytes(list_of_ordinals).decode('ascii').Это дает вам str из значений, но если вам нужен list для обеспечения изменчивости или чего-то подобного вы можете просто преобразовать его (и это все равно быстрее).Например, в ipython микрочипы, преобразующие 45 входных данных:

>>> %%timeit -r5 ordinals = list(range(45))
... list(map(chr, ordinals))
...
3.91 µs ± 60.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*map(chr, ordinals)]
...
3.84 µs ± 219 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*bytes(ordinals).decode('ascii')]
...
1.43 µs ± 49.7 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... bytes(ordinals).decode('ascii')
...
781 ns ± 15.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

Если вы оставите это как str, это занимает ~ 20% времени самого быстрого map Решения;даже обратное преобразование в список все равно занимает менее 40% от самого быстрого map решение.Массовая конвертация через bytes и bytes.decode затем массовое преобразование обратно в list экономит много работы, но как уже отмечалось, работает только в том случае, если все ваши входные данные являются порядковыми числами ASCII (или порядковыми числами в каком-то одном байте на кодировку, зависящую от локали символа, например latin-1).

list(map(chr, [66, 53, 0, 94]))

map(func, *iterables) --> объект карты Создайте итератор, который вычисляет функцию, используя аргументы из каждого из итерируемых объектов.Останавливается, когда исчерпан самый короткий итерируемый параметр.

"Создать итератор"

означает, что он вернет итератор.

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

означает, что функция next() итератора примет одно значение из каждого iterables и передаст каждое из них одному позиционному параметру функции.

Таким образом, вы получаете итератор из функции map() и просто передаете его встроенной функции list() или используете list comprehensions .

В дополнение к приведенным выше ответам в Python 3, мы можем просто создать list результирующих значений из map как

li = []
for x in map(chr,[66,53,0,94]):
    li.append(x)

print (li)
>>>['B', '5', '\x00', '^']

Мы можем обобщить на другом примере, где я был поражен, операции с картой также могут обрабатываться аналогичным образом, как в regex проблема, мы можем написать функцию для получения list элементов для сопоставления и получения результирующего набора одновременно.Бывший.

b = 'Strings: 1,072, Another String: 474 '
li = []
for x in map(int,map(int, re.findall('\d+', b))):
    li.append(x)

print (li)
>>>[1, 72, 474]

Используя понимание списка в python и базовую утилиту map function, это также можно сделать:

chi = [x for x in map(chr,[66,53,0,94])]

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top