在Python 3.x中获取map()以返回一个列表

我试图将一个列表映射为十六进制,然后在其他地方使用该列表。在python 2.6中,这很简单:

答: 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>

如何在Python 3.x上检索映射列表(如上面的一个) ?

或者,有没有更好的方法来做这件事?我的初始列表对象有大约45项和id想把它们转换为十六进制。

580418 次浏览

你为什么不这样做:

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

这叫做列表理解。你可以在谷歌上找到大量的信息,但是这里是Python(2.6)关于列表推导式文档的链接。不过,您可能对Python 3文档更感兴趣。

这样做:

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

在Python 3+中,许多遍历可迭代对象的进程本身都会返回迭代器。在大多数情况下,这最终会节省内存,并应该使程序运行得更快。

如果你最终要做的只是遍历这个列表,甚至不需要将它转换为列表,因为你仍然可以像这样遍历map对象:

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

列表返回映射函数具有节省输入的优点,特别是在交互式会话期间。你可以定义返回list的lmap函数(类似于python2的imap):

lmap = lambda func, *iterable: list(map(func, *iterable))
然后调用lmap而不是map将完成工作: lmap(str, x)list(map(str, x))短5个字符(在本例中是30%),当然也比[str(v) for v in x]短。你也可以为filter创建类似的函数

对最初的问题有一个评论:

我建议重命名为Getting map()以在Python 3中返回一个列表。*因为它适用于所有Python3版本。有办法做到这一点吗?- meawoppl 1月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.5的新功能:

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

感谢附加的拆包概括

更新

我一直在寻找更短的方法,我发现这个方法也很有效:

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

在元组中也可以解包。注意结尾的逗号。这使它成为一个只有1个元素的元组。也就是说,它等价于(*map(chr, [66, 53, 0, 94]),)

它比带列表括号的版本只短了一个字符,但是,在我看来,写起来更好,因为你直接从星号开始——展开语法,所以我觉得它更容易理解。:)

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

map(func, *iterables)——>map对象 创建一个迭代器,该迭代器使用的实参计算函数 每个可迭代对象。当最短可迭代对象耗尽时停止

"创建迭代器"

意味着它将返回一个迭代器。

"使用来自每个可迭代对象的参数计算函数"

意味着迭代器的next()函数将获取每个可迭代对象的一个值,并将每个值传递给函数的一个位置形参。

因此,你从map()函数中获得一个迭代器,并将其传递给list()内置函数或使用列表推导式。

转换我以前的评论以获得更好的可视性:对于完全没有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解决方案;即使转换回列表,它仍然不到最快的map解决方案的40%。通过bytesbytes.decode进行批量转换,然后批量转换回list节省了大量工作,如所述,仅适用于所有输入都是ASCII序数(或每个字符一个字节的特定区域编码序数,例如latin-1)。

除了上面在Python 3中的答案,我们可以简单地从map中创建一个结果值的list

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


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

我们可以通过另一个例子来概括,在map上的操作也可以以类似的方式处理,如在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函数实用程序,也可以做到这一点:

# EYZ0

您可以通过迭代对象中的每个项并将其存储在不同的变量中来尝试从map对象获取列表。

a = map(chr, [66, 53, 0, 94])
b = [item for item in a]
print(b)
>>>['B', '5', '\x00', '^']

另一个选项是创建一个快捷方式,返回一个列表:

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', '^']

在pyton3中最好的方法。X

简单地说,你可以在单行中完成

#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]