Python mapping function acting on a string of numbers

I played with the map function in Python and I was looking for some help in understanding the following behavior:

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

gives you [1, 2, 3, 4, 5] . Obviously int(foo) splashes out 12345 . So what is going on? Since the strings are iterable in nature, the two above strings will be synonymous with

 print [int(x) for x in foo] 

I know that they will produce the same result, but is there something else behind the scenes? Is it more effective or better than the other? Is there another pythonic?

Thanks a lot!

+1
source share
6 answers

map() can be somewhat faster than using lists in some cases, and in some cases a map is slower than understanding lists.

when using the built-in function:

 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 

with lambda , map() becomes slow:

 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 

But in python 3x map() map object is returned, i.e. an iterator

+5
source

Apply a function to each iteration element and return the Results list.

From the documentation for map

int() tries to convert what is passed to an integer and raises a ValueError if you try something stupid, like this:

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

map() will return a list that has the return value of the function you ask it to call for any iterable. If your function returns nothing, you will get a list of None s, for example:

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

This is a short and efficient way to do something like this:

  def verbose_map(some_function,something): results = [] for i in something: results.append(some_function(i)) return results 
+1
source

map can work like this:

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

Basically, it returns a list L , so the ith element of L is the result of computing func on the ith element of your iterable.

So, with int and the string int s, in each iteration of the for loop, this element is a specific character, which, if given for int , is returned as the actual int . The result of calling map on such a line is a list whose elements correspond to the values int ed of the corresponding character in the line.

So, if L = "12345" , then map(int, L) is synonymous with [int(x) for x in L]

Hope this helps

0
source

Yes, backstage is a huge difference. If you print(map) , you will see that it is inline. The built-in function is faster than one written in python, or a large part based on how the language is analyzed, and the map uses the fast iter method, list comprehension is not. Other that there is no difference.

 map(int, '1'*1000000) 

vs.

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

Using CPython and the unix temporary program, the map ends in ~ 3 seconds, list comprehension in ~ 5.

Oh, one more note, this only applies to the fact that the function passed to the card is written in C.

0
source
 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) 

And time:

 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 
0
source

"More effective" is a gang of worms. On this computer it’s faster to use a map with CPython , but list comprehension is faster for 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 shows map() faster even with the optional list() call, which is required

 $ 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 
0
source

Source: https://habr.com/ru/post/1438437/


All Articles