2

我一直在使用 Python 中的 map 函数,我正在寻找一些帮助来理解以下行为:

foo="12345"
print map(int,foo)

给你[1, 2, 3, 4, 5]。显然int(foo)是吐了出来12345。那么究竟发生了什么?由于字符串可以按字符迭代,因此上述两行是否与

print [int(x) for x in foo]

我知道他们会输出相同的结果,但幕后有什么不同吗?一个比另一个更有效还是更好?还有一个“pythonic”吗?

非常感谢!

4

6 回答 6

5

map()在某些情况下可能比使用列表推导要快一些,在某些情况下 map 比列表推导慢。

使用内置函数时:

python -mtimeit -s'xs=xrange(1000)' 'map(int,"1234567890")'
10000 loops, best of 3: 18.3 usec per loop

python -mtimeit -s'xs=xrange(1000)' '[int(x) for x in "1234567890"]'
100000 loops, best of 3: 20 usec per loop

随着lambda,map()变慢:

python -mtimeit -s'xs=xrange(1000)' '[x*10 for x in "1234567890"]'
100000 loops, best of 3: 6.11 usec per loop

python -mtimeit -s'xs=xrange(1000)' 'map(lambda x:x*10,"1234567890")'
100000 loops, best of 3: 11.2 usec per loop

但是,在 python 3x 中map()返回一个映射对象,即一个迭代器

于 2012-10-03T05:51:57.823 回答
1

将函数应用于可迭代的每个项目并返回结果列表。

文档中map

int() 尝试将传递的内容转换为整数,ValueError如果您尝试一些愚蠢的事情,则会引发 a ,如下所示:

>>> int('Hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'Hello'

map()将返回一个列表,该列表具有您要求它调用任何可迭代的函数的返回值。如果您的函数没有返回任何内容,那么您将获得一个Nones 列表,如下所示:

>>> def silly(x):
...   pass
...
>>> map(silly,'Hello')
[None, None, None, None, None]

这是执行以下操作的简短有效的方法:

   def verbose_map(some_function,something):
       results = []
       for i in something:
          results.append(some_function(i))
       return results
于 2012-10-03T05:42:46.740 回答
0

map可以认为是这样工作的:

def map(func, iterable):
    answer = []
    for elem in iterable:
        answer.append(func(elem))
    return answer

基本上,它返回一个列表L,其中第 i 个元素是对可迭代的第 i 个元素L进行计算的结果。func

因此,在 for 循环的每次迭代中,带有sint的字符串int,该元素是一个特定的字符,当给定它时,它int会作为一个实际的int. 调用map此类字符串的结果是一个列表,其元素对应int于字符串中相应字符的 ed 值。

所以是的,如果L = "12345", thenmap(int, L)是同义词[int(x) for x in L]

希望这可以帮助

于 2012-10-03T05:41:20.720 回答
0

是的,幕后有很大的不同。如果你print(map)会看到它是内置的。内置函数的执行速度比用 python 编写的或大多数基于语言解析方式的函数快,map 使用快速 iter 方法,而列表推导则没有。其他没有区别。

map(int, '1'*1000000)

对比

[int(i) for i in '1'*1000000]

使用 CPython 和 unix time 程序,map 在 ~3 秒内完成,列表理解在 ~5 秒内完成。

哦,需要注意的一件事,这只适用于传递给 map 的函数是用 C 语言编写的。

于 2012-10-03T05:41:39.440 回答
0
foo="12345"

In [507]: dis.dis('map(int,foo)')
          0 <109>           28769
          3 STORE_SLICE+0  
          4 LOAD_ATTR       29806 (29806)
          7 <44>           
          8 BUILD_TUPLE     28527
         11 STORE_SLICE+1  

def map(func, iterable):
    answer = []
    for elem in iterable:
        answer.append(func(elem))
    return answer

dis.dis('map(int,foo)')
          0 <109>           28769
          3 STORE_SLICE+0  
          4 LOAD_ATTR       29806 (29806)
          7 <44>           
          8 BUILD_TUPLE     28527
         11 STORE_SLICE+1  
dis.dis('[int(x) for x in foo]')
          0 DELETE_NAME     28265 (28265)
          3 LOAD_GLOBAL     30760 (30760)
          6 STORE_SLICE+1  
          7 SLICE+2        
          8 BUILD_TUPLE     29295
         11 SLICE+2        
         12 SETUP_LOOP      26912 (to 26927)
         15 JUMP_FORWARD    26144 (to 26162)
         18 JUMP_IF_FALSE   23919 (to 23940)

和时间:

In [512]: timeit map(int,foo)
100000 loops, best of 3: 6.89 us per loop

In [513]: def mymap(func, iterable):
     ...:     answer = []
     ...:     for elem in iterable:
     ...:         answer.append(func(elem))
     ...:     return answer

In [514]: timeit mymap(int,foo)
100000 loops, best of 3: 8.29 us per loop

In [515]: timeit [int(x) for x in foo]
100000 loops, best of 3: 7.5 us per loop
于 2012-10-03T05:53:03.687 回答
0

“更高效”是一罐蠕虫。在这台计算机上,将 map 与CPython一起使用会更快,但pypy的列表理解更快

$ python -mtimeit 'map(int,"1234567890")'
100000 loops, best of 3: 8.05 usec per loop
$ python -mtimeit '[int(x) for x in "1234567890"]'
100000 loops, best of 3: 9.33 usec per loop
$ pypy -mtimeit 'map(int,"1234567890")'
1000000 loops, best of 3: 1.18 usec per loop
$ pypy -mtimeit '[int(x) for x in "1234567890"]'
1000000 loops, best of 3: 0.938 usec per loop

即使需要额外的调用,Python3 也显示map()得更快list()

$ python3 -mtimeit 'list(map(int,"1234567890"))'
100000 loops, best of 3: 11.8 usec per loop
$ python3 -mtimeit  '[int(x) for x in "1234567890"]'
100000 loops, best of 3: 13.6 usec per loop
于 2012-10-03T06:20:28.533 回答