I’m trying to map a list into hex, and then use the list elsewhere. In python 2.6, this was easy:
A: Python 2.6:
>>> map(chr, [66, 53, 0, 94]) ['B', '5', 'x00', '^']
However, in Python 3.1, the above returns a map object.
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94]) <map object at 0x00AF5570>
How do I retrieve the mapped list (as in A above) on Python 3.x?
Alternatively, is there a better way of doing this? My initial list object has around 45 items and id like to convert them to hex.
Why aren’t you doing this:
[chr(x) for x in [66,53,0,94]]
It’s called a list comprehension. You can find plenty of information on Google, but here’s the link to the Python (2.6) documentation on list comprehensions. You might be more interested in the Python 3 documenation, though.
In Python 3+, many processes that iterate over iterables return iterators themselves. In most cases, this ends up saving memory, and should make things go faster.
If all you’re going to do is iterate over this list eventually, there’s no need to even convert it to a list, because you can still iterate over the
map object like so:
# Prints "ABCD" for ch in map(chr,[65,66,67,68]): print(ch)
List-returning map function has the advantage of saving typing, especially during interactive sessions. You can define
lmap function (on the analogy of python2’s
imap) that returns list:
lmap = lambda func, *iterable: list(map(func, *iterable))
lmap instead of
map will do the job:
lmap(str, x) is shorter by 5 characters (30% in this case) than
list(map(str, x)) and is certainly shorter than
[str(v) for v in x]. You may create similar functions for
There was a comment to the original question:
I would suggest a rename to Getting map() to return a list in Python 3.* as it applies to all Python3 versions. Is there a way to do this? – meawoppl Jan 24 at 17:58
It is possible to do that, but it is a very bad idea. Just for fun, here’s how you may (but should not) do 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
New and neat in Python 3.5:
[*map(chr, [66, 53, 0, 94])]
Thanks to Additional Unpacking Generalizations
Always seeking for shorter ways, I discovered this one also works:
*map(chr, [66, 53, 0, 94]),
Unpacking works in tuples too. Note the comma at the end. This makes it a tuple of 1 element. That is, it’s equivalent to
(*map(chr, [66, 53, 0, 94]),)
It’s shorter by only one char from the version with the list-brackets, but, in my opinion, better to write, because you start right ahead with the asterisk – the expansion syntax, so I feel it’s softer on the mind. 🙂
list(map(chr, [66, 53, 0, 94]))
map(func, *iterables) –> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
“Make an iterator”
means it will return an iterator.
“that computes the function using arguments from each of the iterables”
means that the next() function of the iterator will take one value of each iterables and pass each of them to one positional parameter of the function.
So you get an iterator from the map() funtion and jsut pass it to the list() builtin function or use list comprehensions.
Converting my old comment for better visibility: For a “better way to do this” without
map entirely, if your inputs are known to be ASCII ordinals, it’s generally much faster to convert to
bytes and decode, a la
bytes(list_of_ordinals).decode('ascii'). That gets you a
str of the values, but if you need a
list for mutability or the like, you can just convert it (and it’s still faster). For example, in
ipython microbenchmarks converting 45 inputs:
>>> %%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)
If you leave it as a
str, it takes ~20% of the time of the fastest
map solutions; even converting back to list it’s still less than 40% of the fastest
map solution. Bulk convert via
bytes.decode then bulk converting back to
list saves a lot of work, but as noted, only works if all your inputs are ASCII ordinals (or ordinals in some one byte per character locale specific encoding, e.g.
In addition to above answers in
Python 3, we may simply create a
list of result values from a
li =  for x in map(chr,[66,53,0,94]): li.append(x) print (li) >>>['B', '5', 'x00', '^']
We may generalize by another example where I was struck, operations on map can also be handled in similar fashion like in
regex problem, we can write function to obtain
list of items to map and get result set at the same time. 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]
Using list comprehension in python and basic map function utility, one can do this also:
chi = [x for x in map(chr,[66,53,0,94])]
You can try getting a list from the map object by just iterating each item in the object and store it in a different variable.
a = map(chr, [66, 53, 0, 94]) b = [item for item in a] print(b) >>>['B', '5', 'x00', '^']
Another option is to create a shortcut, returning a list:
from functools import reduce _compose = lambda f, g: lambda *args: f(g(*args)) lmap = reduce(_compose, (list, map)) >>> lmap(chr, [66, 53, 0, 94]) ['B', '5', 'x00', '^']
Best Way to do this in pyton3.X
Simply you can do this in single line
#Devil input_list = [66, 53, 0, 94] out = [chr(x) for x in input_list] print(out) # you will get the desire output in out list # ['B', '5', 'x00', '^'] #------------------------------ #To retrieve your list use 'ord' original_list = [ord(x) for x in out] print(original_list ) #[66, 53, 0, 94]