Получение карты() для возврата списка в Python 3.икс
Я пытаюсь сопоставить список в hex, а затем использовать список в другом месте. В 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, как конвертировать их в hex.
8 ответов:
этого:
list(map(chr,[66,53,0,94]))
в Python 3+ многие процессы, которые перебирают итераторы, сами возвращают итераторы. В большинстве случаев это приводит к экономии памяти и должно ускорить процесс.
Если все, что вы собираетесь делать, это перебирать этот список в конечном итоге, нет необходимости даже конвертировать его в список, потому что вы все еще можете перебирать
map
объект вот так:# Prints "ABCD" for ch in map(chr,[65,66,67,68]): print(ch)
Почему ты этого не делаешь:
[chr(x) for x in [66,53,0,94]]
это называется понимание списка. Вы можете найти много информации в Гугле, но вот ссылка на документацию Python (2.6) по списку понимания. Вы могли бы быть более заинтересованы в документация Python 3, хотя.
функция возврата списка карт имеет преимущество сохранения ввода, особенно во время интерактивных сеансов. Вы можете определить
lmap
функция (по аналогии с python2imap
), которая возвращает список: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.* как это относится ко всем версиям 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
преобразование мой старый комментарий для лучшей видимости: для "лучшего способа сделать это" без
map
полностью, если ваши входные данные, как известно, являются ординалами ASCII, как правило, гораздо быстрее конвертировать вbytes
и декодирования, а-ляbytes(list_of_ordinals).decode('ascii')
. Это дает вамstr
из значений, но если вам нужноlist
на изменяемость или тому подобное, вы можете просто преобразовать его (и еще быстрее). Например, вipython
microbenchmarks преобразование 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]))
карта(func, * iterables) -- > объект карты Сделайте итератор, который вычисляет функцию, используя аргументы из каждая из итераций. Останавливается, когда исчерпывается самая короткая итерация.
"сделать итератор"
означает, что он вернет итератор.
"который вычисляет функцию, используя аргументы из каждой из итераций"
означает, что следующая () функция итератора будет принимать одно значение каждой итерации и передать каждый из них в один позиционный параметр функции.
таким образом, вы получаете итератор из функции map() и передаете его в встроенную функцию list() или используете понимание списка.
в дополнение к вышеуказанным ответам в
Python 3
, мы можем просто создатьlist
результирующих значений из Amap
как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]