Получение карты() для возврата списка в Python 3.x
Я пытаюсь отобразить список в шестнадцатеричный, а затем использовать список в другом месте. В python 2.6 это было легко:
A: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
Однако, на Python 3.1, приведенное выше возвращает объект карты.
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Как получить отображаемый список (как в A выше) на Python 3.x?
Альтернативно, есть ли лучший способ сделать это? Мой исходный объект списка содержит около 45 элементов, а id - для преобразования их в шестнадцатеричный.
Ответы
Ответ 1
Сделайте это:
list(map(chr,[66,53,0,94]))
В Python 3+ многие процессы, которые перебирают итераторы, возвращают сами итераторы. В большинстве случаев это приводит к экономии памяти и ускоряет работу.
Если все, что вам нужно сделать, это перебрать этот список в конце концов, нет необходимости даже преобразовывать его в список, потому что вы все равно можете перебирать объект map
следующим образом:
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
Ответ 2
Почему вы не делаете этого:
[chr(x) for x in [66,53,0,94]]
Он назвал понимание списка. Вы можете найти много информации о Google, но здесь ссылка на документацию Python (2.6) на понимание списков. Тем не менее вас может заинтересовать документация Python 3.
Ответ 3
Новый и опрятный в Python 3.5:
[*map(chr, [66, 53, 0, 94])]
Благодаря Дополнительные распаковки обобщений
Ответ 4
Функция отображения списков, возвращающая карту, имеет преимущество сохранения набора текста, особенно во время интерактивных сеансов. Вы можете определить функцию lmap
(по аналогии с python2 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
.
Был комментарий к первому вопросу:
Я бы предложил переименовать Get Map(), чтобы вернуть список в Python 3. *, как это применимо ко всем версиям Python3. Есть ли способ сделать это? - meawoppl 24 января в 17:58
Это можно сделать, но это очень плохая идея. Просто для удовольствия, вот как вы можете (но не должны) делать это:
__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
Ответ 5
Я не знаком с Python 3.1, но будет ли это работать?
[chr(x) for x in [66, 53, 0, 94]]
Ответ 6
Преобразование моего старого комментария для лучшей видимости: для "лучшего способа сделать это" без map
полностью, если ваши входы, как известно, являются ординалами ASCII, он обычно намного быстрее конвертируется в bytes
и декодирует a la 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
).
Ответ 7
list(map(chr, [66, 53, 0, 94]))
map (func, * iterables) → объект карты Создайте итератор, который вычисляет функцию, используя аргументы из каждый из повторяющихся. Остановка, когда исчерпана самая короткая итерация.
"Сделать итератор"
означает, что он вернет итератор.
", который вычисляет функцию, используя аргументы из каждого из повторяющихся"
означает, что функция next() итератора будет принимать одно значение каждого итератора и передавать каждый из них в один позиционный параметр функции.
Итак, вы получаете итератор из функции map() funtion и jsut передаете его в список() встроенную функцию или используете списки.
Ответ 8
В дополнение к вышеприведенным ответам в Python 3
мы можем просто создать list
значений результата из map
виде
li = []
for x in map(chr,[66,53,0,94]):
li.append(x)
print (li)
>>>['B', '5', '\x00', '^']
Мы можем обобщить другой пример, где я был поражен, операции на карте также можно обрабатывать аналогично тому, как в проблеме с regex
, мы можем написать функцию для получения list
элементов для сопоставления и получения набора результатов одновременно. Ex.
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]