在 Python 3.x 中获取 map() 以返回列表[重复]
- 2024-12-02 08:42:00
- admin 原创
- 174
问题描述:
我正在尝试将列表映射到十六进制,然后在其他地方使用该列表。在 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 上检索映射列表(如上文 A所示)?
或者,有没有更好的方法?我的初始列表对象大约有 45 个项目,我想将它们转换为十六进制。
解决方案 1:
这样做:
list(map(chr,[66,53,0,94]))
在 Python 3+ 中,许多迭代可迭代对象的进程都会返回迭代器本身。在大多数情况下,这最终会节省内存,并使运行速度更快。
如果您最终要做的只是迭代此列表,则甚至不需要将其转换为列表,因为您仍然可以map
像这样迭代该对象:
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
解决方案 2:
Python 3.5 中的新功能:
[*map(chr, [66, 53, 0, 94])]
感谢额外的解包概括
更新
我一直在寻找更短的方法,我发现这个也有效:
*map(chr, [66, 53, 0, 94]),
元组也可以解包。请注意末尾的逗号。这使其成为一个包含 1 个元素的元组。也就是说,它相当于(*map(chr, [66, 53, 0, 94]),)
它比带有列表括号的版本仅短一个字符,但在我看来,写起来更好,因为您直接从星号开始 - 扩展语法,所以我觉得它更易于理解。:)
解决方案 3:
你为什么不这样做:
[chr(x) for x in [66,53,0,94]]
这叫做列表推导式。你可以在 Google 上找到大量信息,但这里是 Python (2.6) 列表推导式文档的链接。不过,你可能对Python 3 文档更感兴趣。
解决方案 4:
返回列表的 map 函数具有节省输入量的优点,尤其是在交互式会话期间。您可以定义返回列表的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
。
对原始问题有一条评论:
我建议将“在 Python 3.* 中获取 map() 返回列表”重命名,因为它适用于所有 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
解决方案 5:
转换我的旧评论以获得更好的可见性:对于“更好的方法” 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
,则所需时间约为最快map
解决方案的 20%;即使将其转换回列表,所需时间仍不到最快map
解决方案的 40%。通过 进行批量转换bytes
,bytes.decode
然后批量转换回list
可节省大量工作,但如上所述,只有当您的所有输入都是 ASCII 序数(或每个字符一个字节的特定语言环境编码的序数,例如latin-1
)时才有效。
解决方案 6:
list(map(chr, [66, 53, 0, 94]))
map(func, *iterables) --> map 对象创建一个迭代器,使用每个可迭代对象的参数计算函数。当最短的可迭代对象耗尽时停止。
“创建一个迭代器”
表示它将返回一个迭代器。
“使用来自每个可迭代对象的参数来计算函数”
意味着迭代器的 next() 函数将获取每个可迭代对象的一个值,并将它们每个传递给函数的一个位置参数。
因此,您可以从 map() 函数中获取一个迭代器,然后将其传递给 list() 内置函数或使用列表推导。
解决方案 7:
使用 python 中的列表推导和基本 map 函数实用程序,也可以做到这一点:
chi = [x for x in map(chr,[66,53,0,94])]
解决方案 8:
您可以尝试从 map 对象中获取列表,只需迭代对象中的每个项目并将其存储在不同的变量中即可。
a = map(chr, [66, 53, 0, 94])
b = [item for item in a]
print(b)
>>>['B', '5', 'x00', '^']
解决方案 9:
另一个选择是创建一个快捷方式,返回一个列表:
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', '^']
解决方案 10:
在 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]
解决方案 11:
除了上面的答案之外,我们还可以简单地从aPython 3
创建一个list
结果值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]