开发者

What is more efficient in python new array creation or in place array manipulation?

Say I have an array with a couple hundred elements. I need to iterate of the array and replace one or more items in the array with some other item. Which strategy is more efficient in python in terms of speed (I'm not worried about memory)?

For example: I have an array

 my_array = [1,2,3,4,5,6]

I want to replace the first 3 elements with one element with the value 123.

Option 1 (inline):

my_array = [1,2,3,4,5,6]
my_array.remove(0,3)
my_array.insert(0,123)

Option2 (new array creation):

my_array = [1,2,3,4,5,6]
my_array = my_array[3:]    
my_array.insert(开发者_如何学编程0,123)

Both of the above will options will give a result of:

>>> [123,4,5,6]

Any comments would be appreciated. Especially if there is options I have missed.


If you want to replace an item or a set of items in a list, you should never use your first option. Removing and adding to a list in the middle is slow (reference). Your second option is also fairly inefficient, since you're doing two operations for a single replacement.

Instead, just do slice assignment, as eiben's answer instructs. This will be significantly faster and more efficient than either of your methods:

>>> my_array = [1,2,3,4,5,6]
>>> my_array[:3] = [123]
>>> my_array
[123, 4, 5, 6]


arr[0] = x

replaces the 0th element with x. You can also replace whole slices.

>>> arr = [1, 2, 3, 4, 5, 6]
>>> arr[0:3] = [8, 9, 99]
>>> arr
[8, 9, 99, 4, 5, 6]
>>> 

And generally it's unclear what you're trying to achieve. Please provide more information or an example.


OK, as for your update. The remove method doesn't work (remove needs one argument). But the slicing I presented works for your case too:

>>> arr
[8, 9, 99, 4, 5, 6]
>>> arr[0:3] = [4]
>>> arr
[4, 4, 5, 6]

I would guess it's the fastest method, but do try it with timeit. According to my tests it's twice as fast as your "new array" approach.


If you're looking speed efficience and manipulate series of integers, You should use the standard array module instead:

>>> import array
>>> my_array = array.array('i', [1,2,3,4,5,6])
>>> my_array = my_array[3:]
>>> my_array.insert(0,123)
>>> my_array
array('i', [123, 4, 5, 6])


The key thing is to avoid moving large numbers of list items more than absolutely have to. Slice assignment, as far as i'm aware, still involves moving the items around the slice, which is bad news.

How do you recognise when you have a sequence of items which need to be replaced? I'll assume you have a function like:

def replacement(objects, startIndex):
    "returns a pair (numberOfObjectsToReplace, replacementObject), or None if the should be no replacement"

I'd then do:

def replaceAll(objects):
    src = 0
    dst = 0
    while (src < len(objects)):
        replacementInfo = replacement(objects, src)
        if (replacementInfo != None):
            numberOfObjectsToReplace, replacementObject = replacementInfo
        else:
            numberOfObjectsToReplace = 1
            replacementObject = objects[src]
        objects[dst] = replacementObject
        src = src + numberOfObjectsToReplace
        dst = dst + 1
    del objects[dst:]

This code still does a few more loads and stores than it absolutely has to, but not many.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜