Getting a map() to return a list in Python 3.x
我正在尝试将列表映射为十六进制,然后在其他地方使用该列表。在Python2.6中,这很容易:
答:Python 2.6:
1 2 | >>> map(chr, [66, 53, 0, 94]) ['B', '5', '\x00', '^'] |
但是,在python 3.1中,上面的返回一个map对象。
B:Python 3.1:
1 2 | >>> map(chr, [66, 53, 0, 94]) <map object at 0x00AF5570> |
如何在python 3.x上检索映射列表(如上所述)?
或者,是否有更好的方法来实现这一点?我的初始列表对象有大约45个项目,我想把它们转换成十六进制。
这样做:
1 | list(map(chr,[66,53,0,94])) |
在python 3+中,许多迭代iterables的进程本身返回迭代器。在大多数情况下,这最终会节省内存,并且会使事情发展得更快。
如果您所要做的就是最终对这个列表进行迭代,那么甚至不需要将它转换为列表,因为您仍然可以像这样对
1 2 3 | # Prints"ABCD" for ch in map(chr,[65,66,67,68]): print(ch) |
你为什么不这样做:
1 | [chr(x) for x in [66,53,0,94]] |
这叫做列表理解。您可以在Google上找到很多信息,但这里有关于列表理解的python(2.6)文档的链接。不过,您可能对python 3文档更感兴趣。
python 3.5中的新的和整洁的:
1 | [*map(chr, [66, 53, 0, 94])] |
由于额外的解包归纳
更新
我一直在寻找较短的方法,发现这一方法也有效:
1 | *map(chr, [66, 53, 0, 94]), |
解包也可以用元组进行。注意末尾的逗号。这使它成为一个由1个元素组成的元组。也就是说,它相当于
它比带括号的版本短了一个字符,但在我看来,最好还是写下来,因为你从前面的星号开始——扩展语法,所以我觉得它在心里更柔和。:)
列表返回映射函数具有保存键入的优点,特别是在交互式会话中。您可以定义返回列表的
1 | lmap = lambda func, *iterable: list(map(func, *iterable)) |
然后调用
对最初的问题有一个评论:
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
这是可能的,但这是一个非常坏的主意。只是为了好玩,你可以(但不应该)这样做:
1 2 3 4 5 6 7 | __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,但是这行吗?
1 | [chr(x) for x in [66, 53, 0, 94]] |
将我以前的评论转换为更好的可见性:为了在不完全使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | >>> %%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) |
如果您将其保留为
使用python中的列表理解和基本的map函数实用程序,您也可以这样做:
除了上述在
1 2 3 4 5 6 | li = [] for x in map(chr,[66,53,0,94]): li.append(x) print (li) >>>['B', '5', '\x00', '^'] |
我们可以用另一个例子来概括我被击中的地方,地图上的操作也可以用类似于
1 2 3 4 5 6 7 | 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] |
1 | 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"
意味着它将返回迭代器。
"that computes the function using arguments from each of the iterables"
意味着迭代器的next()函数将获取每个iterables的一个值,并将每个iterables传递给函数的一个位置参数。
所以从map()函数中得到一个迭代器,jsut将它传递给list()内置函数或使用list理解。