首页 文章

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

提问于
浏览
387

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

A: 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个项目,id喜欢将它们转换为十六进制 .

9 回答

  • 82

    做这个:

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

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

    如果所有你甚至不需要将它转换为列表,因为你仍然可以像这样迭代 map 对象:

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

    你为什么不这样做:

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

    它被称为列表理解 . 您可以在Google上找到大量信息,但here's the link to the Python (2.6) documentation on list comprehensions . 不过,你可能对the Python 3 documenation更感兴趣 .

  • 590

    Python 3.5中的新功能:

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

    感谢Additional Unpacking Generalizations

    UPDATE

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

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

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

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

  • 20

    列表返回映射功能具有节省键入的优点,尤其是在交互式会话期间 . 您可以定义返回列表的 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 创建类似的功能 .

    对原始问题有评论:

    我建议重命名为获取map()以返回Python 3中的列表 . *因为它适用于所有Python3版本 . 有没有办法做到这一点? - meawoppl 1月24日17:58

    有可能做到这一点,但这是一个非常糟糕的主意 . 只是为了好玩,你可以这样做( but should not ):

    __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
    
  • 0

    我不熟悉Python 3.1,但这会有用吗?

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

    转换my old comment以获得更好的可见性:对于完全没有 map 的"better way to do this",如果您的输入已知为ASCII序数,则转换为 bytes 并解码,通常要快得多_a7122214_ . 这会让你得到一个 str 的值,但如果你需要 list 可变性等,你可以转换它(它仍然更快) . 例如,在转换45个输入的 ipython 微基准测试中:

    >>> %%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% . 批量转换通过 bytesbytes.decode 然后批量转换回 list 节省了大量工作,但如上所述,仅当所有输入都是ASCII序数(或每个字符区域特定编码的某个字节中的序数,例如 latin-1 )时才有效 .

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

    map(func,* iterables) - > map object创建一个迭代器,使用每个iterables的参数计算函数 . 当最短的可迭代用尽时停止 . “做一个迭代器”

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

    “使用来自每个迭代的参数计算函数”

    表示迭代器的next()函数将获取每个iterables的一个值,并将它们中的每一个传递给函数的一个位置参数 .

    所以你从map()函数得到一个迭代器,jsut将它传递给list()内置函数或使用列表推导 .

  • 11

    除了 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]
    
  • 63

    在python和基本 Map 功能实用程序中使用列表理解,也可以这样做:

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

相关问题