2017/01/19

How to do array initialization on python efficiently

Question

Suppose we would like to create an array with 100 elements.
2 types of elements will be tested
  • None
  • integers from 0 to 99

Methods

3 ways to initialize an array
  • By append

def byAppend():
    a = []
    for i in xrange(100):
        a.append(None)

def byAppendInit():
    a = []
    for i in xrange(100):
        a.append(i)
  • By list comprehension

def byListComprehension():
    [None for i in xrange(100)]

def byComprehensionInit():
    [i for i in xrange(100)]
  • By multiplication

def byMultiplication():
    [None] * 100

def byMultiplicationInit():
    a = [None] * 100
    for i in xrange(100):
        a[i] = i

Results


import timeit
print 'By append'
print(timeit.timeit('byAppend()', setup="from __main__ import byAppend"))
print 'By append init'
print(timeit.timeit('byAppendInit()', setup="from __main__ import byAppendInit"))
print 'By list comprehension'
print(timeit.timeit('byListComprehension()', setup="from __main__ import byListComprehension"))
print 'By list comprehensionInit'
print(timeit.timeit('byComprehensionInit()', setup="from __main__ import byComprehensionInit"))
print 'By byMultiplication'
print(timeit.timeit('byMultiplication()', setup="from __main__ import byMultiplication"))
print 'By byMultiplication init'
print(timeit.timeit('byMultiplicationInit()', setup="from __main__ import byMultiplicationInit"))
Output from consoles
C:\Python27\python.exe C:/Users/Mond/PycharmProjects/hackercup/round1/test.py
By append
10.2452175728
By append init
9.83314044088

By list comprehension
4.45988583823
By list comprehensionInit
4.37547215318

By byMultiplication
0.840903578289
By byMultiplication init
5.83873665989

Conclusion

  • If you need to create a “fixed sized” array only, multiplication is the fastest.
  • If you need to initialize array with some constants, list comprehension performs better.
  • Never ever using the way for appending.

Gotcha

For 2d array initialization, you must be careful not to do it via multiplication.
Below are codes for initializing a 2D array with 3 rows and try to add a string hello to the first array

a = [[]] * 3
a[0].append('hello')
print a
What a will be output is
[['hello'], ['hello'], ['hello']]
instead of
[['hello'], [], []]
Therefore, we can see initializing 2D array via multiplication is not a good way as they are all the same array even though arrays seems to be multiplied (initialized).
The proper way is using list comprehension
# The underscore `_` means I do not care what value it is
a = [[] for _ in xrange(3)]

a[0].append('hello')
print a
Then, a will be output as
[['hello'], [], []]

沒有留言:

張貼留言