Получение карты() для возврата списка в 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 366

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, хотя.

новый и аккуратный в Python 3.5:

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

спасибо Дополнительные Распаковки Обобщения

функция возврата списка карт имеет преимущество сохранения ввода, особенно во время интерактивных сеансов. Вы можете определить 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 тоже.

был комментарий к исходный вопрос:

Я бы предложил переименовать в получение 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

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

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

преобразование мой старый комментарий для лучшей видимости: для "лучшего способа сделать это" без 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 результирующих значений из A 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]