获取map()以返回Python 3.x中的列表

moz*_*ami 480 python list python-3.x map-function

我正在尝试将列表映射到十六进制,然后在其他地方使用列表.在python 2.6中,这很简单:

答: Python 2.6:

>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
Run Code Online (Sandbox Code Playgroud)

但是,在Python 3.1中,上面返回了一个map对象.

B: Python 3.1:

>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Run Code Online (Sandbox Code Playgroud)

如何在Python 3.x上检索映射列表(如上面的A中所示)?

或者,有更好的方法吗?我的初始列表对象有大约45个项目,id喜欢将它们转换为十六进制.

Tri*_*ych 719

做这个:

list(map(chr,[66,53,0,94]))
Run Code Online (Sandbox Code Playgroud)

在Python 3+中,许多迭代迭代的进程返回迭代器本身.在大多数情况下,这最终会节省内存,并且应该让事情变得更快.

如果您要做的就是最终遍历此列表,则无需将其转换为列表,因为您仍然可以map像这样迭代对象:

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

  • @Andrew实际上Hugh正在使用生成器理解器,它会做同样的事情.请注意括号而不是方括号. (17认同)
  • 当然,你也可以迭代这个:([65,66,67,68]中的x的chr(x)).它甚至不需要地图. (14认同)
  • 当已知值为ASCII/latin-1时,替代解决方案(对于大输入也更快)是在C层进行批量转换:`bytes(sequence_of_ints_in_range_0_to_256).decode('latin-1')`这使得`通过避免对每个元素进行Python函数调用来支持仅使用C级函数调用对所有元素进行批量转换,从而更快地实现str.如果你真的需要单个字符的`list`,你可以将上面的内容包装在`list`中,但由于`str`已经是它自己字符的可迭代,你唯一的理由就是你需要可变性. (5认同)
  • @hughdbrown 在迭代复杂函数、大型数据集或流时,使用 3.1 的 `map` 的论点将是惰性求值。 (4认同)
  • “参数错误”仅出现在 PDB 调试器中。请参阅:http://stackoverflow.com/questions/17290314/possible-bug-in-pdb-module-in-python-3-when-using-list-generators (2认同)

Mar*_*off 94

你为什么不这样做:

[chr(x) for x in [66,53,0,94]]
Run Code Online (Sandbox Code Playgroud)

它被称为列表理解.您可以在Google上找到大量信息,但这里是关于列表推导的Python(2.6)文档的链接.但是,您可能对Python 3文档更感兴趣.

  • 我想因为它更冗长,你必须写一个额外的变量(两次)...如果操作更复杂并且你最终写了一个lambda,或者你还需要丢弃一些元素,我认为理解是明确的更好而不是地图+过滤器,但如果您已经拥有要应用的功能,则地图更简洁. (45认同)
  • Hmmmm.也许需要在列表推导,生成器,map(),zip()以及python中的许多其他快速迭代优点上进行一般性发布. (4认同)
  • map(chr,[66,53,0,94])绝对比`[chr(x)for [66,53,0,94]]中的x简洁。 (4认同)

Isr*_*man 91

Python 3.5中的新功能:

[*map(chr, [66, 53, 0, 94])]
Run Code Online (Sandbox Code Playgroud)

感谢额外的拆包概括

UPDATE

总是寻求更短的方式,我发现这个也有效:

*map(chr, [66, 53, 0, 94]),
Run Code Online (Sandbox Code Playgroud)

解包也适用于元组.注意最后的逗号.这使它成为1元素的元组.也就是说,它相当于(*map(chr, [66, 53, 0, 94]),)

只有一个带有列表括号的版本的char更短,但是,在我看来,写得更好,因为你开始使用星号 - 扩展语法,所以我觉得它在头脑上更柔和.:)

  • @Quelklef`list()`看起来并不整洁 (11认同)
  • @Quelklef:此外,由于不需要查找`list`构造函数并调用通用函数调用机制,因此解包方法更快.长期投入,无关紧要; 对于一个短的,它可以产生很大的不同.使用上面的代码将输入作为`元组`,因此不会重复重构,`ipython`微基准测试显示`list()`换行方法比解包需要大约20%.请注意,从绝对意义上说,我们谈论的是150 ns,这是微不足道的,但你明白了. (4认同)
  • “*map()”在“Python 3.6”上给出语法错误:“此处不能使用星号表达式”。您需要将其放入“列表”中:“[ *map() ]” (4认同)
  • @ALH您在命令末尾错过了逗号。容易犯的错误! (3认同)

Bor*_*lik 23

列表返回映射功能具有节省键入的优点,尤其是在交互式会话期间.您可以定义返回列表的lmap函数(类似于python2 imap):

lmap = lambda func, *iterable: list(map(func, *iterable))
Run Code Online (Sandbox Code Playgroud)

然后调用lmap而不是map将完成工作: lmap(str, x)缩短5个字符(在这种情况下为30%),list(map(str, x))而且肯定比短[str(v) for v in x].您也可以创建类似的功能filter.

对原始问题有评论:

我建议重命名为获取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
Run Code Online (Sandbox Code Playgroud)


Sha*_*ger 5

转换我的旧评论以获得更好的可见性:对于“更好的方法”而不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)
Run Code Online (Sandbox Code Playgroud)

如果将其保留为str,则需要最快map解决方案的大约 20% 的时间;即使转换回列表,它仍然不到最快map解决方案的40% 。通过批量转换bytesbytes.decode再批量转换回list节省了大量的工作,如前所述,只有当所有的输入都是ASCII序(或序号在每个字符设置特定编码一些一个字节,如工程latin-1)。