2

I'm learning Python, and I was trying to change a list in different ways. For instance, if I have list called names like this:

names = ["David", "Jake", "Alex"]

and I want to add the name "Carter" into the list, what is the most efficient way to accomplish this? Here's some of the things I can do:

names.append("Carter")

names = names + ["Carter"]

names += ["Carter"]
  • 3
    I recommend using the `timeit` module to investigate this. – Paul H Jan 27 '16 at 21:49
  • 6
    Premature optimization. Focus on idiom rather than efficiency at this point. Any work, `names.append("Carter")` is most idiomatic IMHO – dawg Jan 27 '16 at 21:49
  • 2
    @dawg, curious how you'd feel (in terms of idiomatic-ness) about `names = [*names, 'Carter']` in python 3.5 – Paul H Jan 27 '16 at 21:50
  • 5
    @PaulH: Ugly. Not obvious. Not idiomatic. Why do that? – dawg Jan 27 '16 at 21:53
  • 4
    the time difference would presumably be a matter of microseconds. idiomatically,`names.append` is best because it's clear and obvious what you're doing to `names`. – n1c9 Jan 27 '16 at 21:56
  • generalized unpacking was a highly publicized enhancement of python 3.5. i'm just curious how the world is taking to it. (@dawg) – Paul H Jan 27 '16 at 21:57
  • 1
    If bookended like this `[*list1, 'Carter', *list2, 'Bob']` as opposed to `list1+['Carter']+list2+['Bob']` -- different story I suppose – dawg Jan 27 '16 at 22:05

2 Answers2

7

append is the fastest. Here is how you build a small profile using the timeit module

import timeit
a = (timeit.timeit("l.append('Cheese')", setup="l=['Meat', 'Milk']"))
b = (timeit.timeit("l+=['Cheese']", setup="l=['Meat', 'Milk']"))
c = (timeit.timeit("append('Cheese')", setup="l=['Meat', 'Milk'];append = l.append"))
print ('a', a)
print ('b', b)
print ('c', c)
print ("==> " , (c < a < b))

As you can see, In python the access to the method append takes half of the time as the l.append itself...

a 0.08502503100316972

b 0.1582659209962003

c 0.041991976962890476

==> True

Yoav Glazner
  • 7,936
  • 1
  • 19
  • 36
1

You can use the timeit package as shown in this blog post.

Here is a complete code running the tests 20000 times each test:

import timeit
t = 20000

print( "Addition (lst = lst + [4, 5, 6])" )
print( timeit.Timer("lst = lst + [4, 5, 6]", "lst = [1, 2, 3]").timeit(t) )
print( "Addition (lst += [4, 5, 6])" )
print( timeit.Timer("lst += [4, 5, 6]", "lst = [1, 2, 3]").timeit(t) )
print( "Extend (lst.extend([4, 5, 6]))" )
print( timeit.Timer("lst.extend([4, 5, 6])", "lst = [1, 2, 3]").timeit(t) )
print( "Append loop (lst.append([4, 5, 6]))" )
print( timeit.Timer("for i in [4,5,6]: lst.append(i)", "lst = [1,2,3]").timeit(t) )
print( "Append loop, no dot (a(i))" )
# a.b does a lookup, we don't want that, it is slower. Instead use b = a.b 
# then use b.
print( timeit.Timer("""a = lst.append
for i in [4,5,6]: a(i)""", "lst = [1,2,3]").timeit(t) )

And the results (Python 3.4.4) are:

Addition (lst = lst + [4, 5, 6])
1.947201736000352
Addition (lst += [4, 5, 6])
0.0015889199999037373
Extend (lst.extend([4, 5, 6]))
0.0020685689996753354
Append loop (lst.append([4, 5, 6]))
0.0047527769997941505
Append loop, no dot (a(i))
0.003853704999983165
perror
  • 7,071
  • 16
  • 58
  • 85