![](/img/trans.png)
[英]Getting a map() to return a list instead of map object in Python 3.x
[英]Getting a map() to return a list in Python 3.x
我正在尝试将 map 列表转换为十六进制,然后在其他地方使用该列表。 在 python 2.6 中,这很容易:
答: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
但是,在 Python 3.1 中,上述返回 map object。
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
如何检索 Python 3.x 上的映射列表(如上图A )?
或者,有没有更好的方法来做到这一点? 我的初始列表 object 有大约 45 个项目,我喜欢将它们转换为十六进制。
做这个:
list(map(chr,[66,53,0,94]))
在 Python 3+ 中,许多迭代可迭代对象的进程本身返回迭代器。 在大多数情况下,这最终会节省内存,并且应该让事情变得更快。
如果您要做的只是最终迭代此列表,则甚至无需将其转换为列表,因为您仍然可以像这样迭代map
对象:
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
Python 3.5 中的新功能:
[*map(chr, [66, 53, 0, 94])]
感谢额外的解包概括
更新
一直在寻找更短的方法,我发现这个方法也有效:
*map(chr, [66, 53, 0, 94]),
解包也适用于元组。 注意最后的逗号。 这使它成为 1 个元素的元组。 也就是说,它等价于(*map(chr, [66, 53, 0, 94]),)
它比带有列表括号的版本短了一个字符,但是,在我看来,最好写,因为你从星号开始——扩展语法,所以我觉得它更柔软。 :)
你为什么不这样做:
[chr(x) for x in [66,53,0,94]]
它被称为列表理解。 您可以在 Google 上找到大量信息,但这里是列表推导上 Python (2.6) 文档的链接。 不过,您可能对 Python 3 文档更感兴趣。
返回列表的地图功能具有节省打字的优势,尤其是在交互式会话期间。 您可以定义返回列表的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.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
,则需要最快的map
解决方案大约 20% 的时间; 即使转换回列表,它仍然不到最快map
解决方案的 40%。 通过bytes
和bytes.decode
进行批量转换,然后批量转换回list
可以节省大量工作,但如前所述,仅当您的所有输入都是 ASCII 序数(或每个字符区域设置特定编码的某个字节中的序数,例如latin-1
)时才有效)。
list(map(chr, [66, 53, 0, 94]))
map(func, *iterables) --> map object 创建一个迭代器,使用每个可迭代对象的参数计算函数。 当最短的迭代用完时停止。
“做一个迭代器”
意味着它将返回一个迭代器。
“使用来自每个可迭代对象的参数计算函数”
意味着迭代器的 next() 函数将获取每个可迭代对象的一个值,并将它们中的每一个传递给函数的一个位置参数。
所以你从 map() 函数中得到一个迭代器,然后将它传递给 list() 内置函数或使用列表推导。
除了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 函数实用程序,也可以这样做:
chi = [x for x in map(chr,[66,53,0,94])]
您可以尝试通过迭代对象中的每个项目并将其存储在不同的变量中来从地图对象中获取列表。
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]
在Python 3中,地图,过滤器等的功能已更改。 它不会返回列表,而是返回一个迭代器,我们可以对其进行迭代。 因此,在您的情况下,迭代器是map对象。 因此就做
lst = [value for value in map(chr, [66, 53, 0, 94])]
这应该很好
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.