2

I came across a few articles and StackOverflow discussions where it is usually recommended to use list comprehension while dealing with lists.

I usually come across a common loop structure where I have a list and I have to process it and store the results in a new list.

So something like (For the sake of an example):

1) create a big list of strings for playing around purpose

from random import choice
from string import ascii_uppercase
import time

oldlist = ([''.join(choice(ascii_uppercase) 
                    for i in range(10)) for x in range(1000000)])

2) process it using loop, list comprehension, and maps loop variant 1:

start_time = time.time()
newlist = []
for word in oldlist:
    newlist.append(word.lower())
print(time.time()-start_time) # 0.1368732452392578

loop variant 2:

start_time = time.time()
newlist = []
append = newlist.append
for word in oldlist:
    append(word.lower())
print(time.time()-start_time)# 0.1112520694732666

list comp:

start_time = time.time()
newlist = [word.lower() for word in oldlist]
print(time.time()-start_time) # 0.07511067390441895

map:

start_time = time.time()
newlist = map(str.lower, oldlist)
print(time.time()-start_time) # 3.0994415283203125e-06

Can I assume that in such situation map should always be used as its faster than the rest? List comprehension is considered more readable according to various articles but should readability be the first priority or a significant amount of speed?

Note: I just took an average of five iterations so these times values might change a bit. However, it gives us an indication. Python version: 3

utengr
  • 3,225
  • 3
  • 29
  • 68
  • @MaximeLorant I think that one is more generic. I have a specific situation which I am asking about. – utengr Oct 17 '17 at 12:15
  • 1
    You should use the `timeit` module for such benchmarks. – bruno desthuilliers Oct 17 '17 at 12:39
  • 2
    `map(str.lower, oldlist)` doesn't return a list so this is not a fair comparison. If you add the list call it takes about the same for both. And considering that map applies a function to every element of an iterable every map/list comprehension comparison is as specific as this one. – ayhan Oct 17 '17 at 13:02
  • @ayhan missed that. It clears the confusion. With list, map takes slightly more than list comp. – utengr Oct 17 '17 at 13:54

1 Answers1

2

Performance is not always the first priority when writing code. In a lot of case, we might not care about the µs lost in the list comprehension, if it helps reading and maintaining the code later.

I believe list comprehension are more easier to read and understand than map, despite the small performance lost.

EDIT, as ayhan described in comments, your example is biased since map returns a generator, so it does not generate anything until iterated over, while the list comprehension compute the whole list on declaration.

Maxime Lorant
  • 34,607
  • 19
  • 87
  • 97
  • can you add the explanation of ayhanś comment to your answer so I can accept it as an answer. I was getting different results because I didn't compare it in a fair way. – utengr Oct 17 '17 at 14:12
  • @engr_s I can, but since it was not my point (I was generally speaking, and in Py3, map produces a generator indeed), it would just be stealing an answer :) – Maxime Lorant Oct 17 '17 at 14:30
  • I know but Ayhan used it in the comment so he may be fine with it :) I thought its more readable for others to see my mistake in the comparison if it's mentioned in one of the answers than in a comment. If Ayhan adds it as a separate answer, I will gladly accept that too. – utengr Oct 17 '17 at 14:35