Google Mail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Most efficient way to "pre-grow" a list?
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 1 - 25 of 30 - Collapse all  -  Translate all to Translated (View all originals)   Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Follow-up To:
Add Cc | Add Follow-up to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers that you hear
 
kj  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 12:12
Newsgroups: comp.lang.python
From: kj <no.em...@please.post>
Date: Fri, 6 Nov 2009 12:12:40 +0000 (UTC)
Local: Fri 6 Nov 2009 12:12
Subject: Most efficient way to "pre-grow" a list?

In Perl one can assign a value to any element of an array, even to
ones corresponding to indices greater or equal than the length of
the array:

  my @arr;
  $arr[999] = 42;

perl grows the array as needed to accommodate this assignment.  In
fact one common optimization in Perl is to "pre-grow" the array to
its final size, rather than having perl grow it piecemeal as required
by assignments like the one above:

  my @arr;
  $#arr = 999_999;

After assigning to $#arr (the last index of @arr) as shown above,
@arr has length 1,000,000, and all its elements are initialized to
undef.

In Python the most literal translation of the first code snippet
above triggers an IndexError exception:

>>> arr = list()
>>> arr[999] = 42

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range

In fact, one would need to pre-grow the list sufficiently to be
able to make an assignment like this one.  I.e. one needs the
equivalent of the second Perl snippet above.

The best I can come up with is this:

arr = [None] * 1000000

Is this the most efficient way to achieve this result?

TIA!

kynn


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Rubin  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 12:34
Newsgroups: comp.lang.python
From: Paul Rubin <http://phr...@NOSPAM.invalid>
Date: 06 Nov 2009 04:34:08 -0800
Local: Fri 6 Nov 2009 12:34
Subject: Re: Most efficient way to "pre-grow" a list?

kj <no.em...@please.post> writes:
> >>> arr[999] = 42
>    ...
> The best I can come up with is this:
> arr = [None] * 1000000
> Is this the most efficient way to achieve this result?

If you're talking about an array of ints, use the array module.
You might also look at numpy.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jon Clements  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 14:11
Newsgroups: comp.lang.python
From: Jon Clements <jon...@googlemail.com>
Date: Fri, 6 Nov 2009 06:11:44 -0800 (PST)
Local: Fri 6 Nov 2009 14:11
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 6, 12:12 pm, kj <no.em...@please.post> wrote:

[snip]

> In fact, one would need to pre-grow the list sufficiently to be
> able to make an assignment like this one.  I.e. one needs the
> equivalent of the second Perl snippet above.

> The best I can come up with is this:

> arr = [None] * 1000000

> Is this the most efficient way to achieve this result?

That's a good as it gets I think.

If sparsely populated I might be tempted to use a dict (or maybe
defaultdict):

d = {999: 42, 10673: 123}
for idx in xrange(1000000): # Treat it as though it's a list of
1,000,000 items...
  print 'index %d has a value of %d' % (idx, d.get(idx, None))

Efficiency completely untested.

Jon.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andre Engels  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 15:12
Newsgroups: comp.lang.python
From: Andre Engels <andreeng...@gmail.com>
Date: Fri, 6 Nov 2009 16:12:59 +0100
Local: Fri 6 Nov 2009 15:12
Subject: Re: Most efficient way to "pre-grow" a list?

It depends - what do you want to do with it? My first hunch would be
to use a dictionary instead of a list, then the whole problem
disappears. If there is a reason you don't want to do that, what is
it?

--
André Engels, andreeng...@gmail.com


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Raymond Hettinger  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 17:39
Newsgroups: comp.lang.python
From: Raymond Hettinger <pyt...@rcn.com>
Date: Fri, 6 Nov 2009 09:39:09 -0800 (PST)
Local: Fri 6 Nov 2009 17:39
Subject: Re: Most efficient way to "pre-grow" a list?
[kj]

> In fact, one would need to pre-grow the list sufficiently to be
> able to make an assignment like this one.  I.e. one needs the
> equivalent of the second Perl snippet above.

> The best I can come up with is this:

> arr = [None] * 1000000

> Is this the most efficient way to achieve this result?

Yes.

Raymond


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Emily Rodgers  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 18:11
Newsgroups: comp.lang.python
From: "Emily Rodgers" <em...@nospam.com>
Date: Fri, 6 Nov 2009 18:11:47 -0000
Local: Fri 6 Nov 2009 18:11
Subject: Re: Most efficient way to "pre-grow" a list?

"Andre Engels" <andreeng...@gmail.com> wrote in message

news:mailman.2696.1257520404.2807.python-list@python.org...

>On Fri, Nov 6, 2009 at 1:12 PM, kj <no.em...@please.post> wrote:
[snip]
>> arr = [None] * 1000000

>> Is this the most efficient way to achieve this result?

> It depends - what do you want to do with it? My first hunch would be
> to use a dictionary instead of a list, then the whole problem
> disappears. If there is a reason you don't want to do that, what is
> it?

> --
> André Engels, andreeng...@gmail.com

I second this. It might seem a sensible thing to do in perl, but I can't
imagine what you would actually want to do it for! Seems like an odd thing
to want to do!

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
kj  
View profile   Translate to Translated (View Original)
 More options 6 Nov, 21:03
Newsgroups: comp.lang.python
From: kj <no.em...@please.post>
Date: Fri, 6 Nov 2009 21:03:31 +0000 (UTC)
Local: Fri 6 Nov 2009 21:03
Subject: Re: Most efficient way to "pre-grow" a list?
In <hd1os1$aq...@cam-news1.cambridge.arm.com> "Emily Rodgers" <em...@nospam.com> writes:

>"Andre Engels" <andreeng...@gmail.com> wrote in message
>news:mailman.2696.1257520404.2807.python-list@python.org...
>>On Fri, Nov 6, 2009 at 1:12 PM, kj <no.em...@please.post> wrote:
>[snip]
>>> arr = [None] * 1000000

>>> Is this the most efficient way to achieve this result?

>> It depends - what do you want to do with it? My first hunch would be
>> to use a dictionary instead of a list, then the whole problem
>> disappears. If there is a reason you don't want to do that, what is
>> it?
>I second this. It might seem a sensible thing to do in perl, but I can't
>imagine what you would actually want to do it for! Seems like an odd thing
>to want to do!

As I said, this is considered an optimization, at least in Perl,
because it lets the interpreter allocate all the required memory
in one fell swoop, instead of having to reallocate it repeatedly
as the array grows.  (Of course, like with all optimizations,
whether it's worth the bother is another question.)

Another situation where one may want to do this is if one needs to
initialize a non-sparse array in a non-sequential order, e.g. if
that's the way the data is initially received by the code.  Of
course, there are many ways to skin such a cat; pre-allocating the
space and using direct list indexing is just one of them.  I happen
to think it is a particularly straighforward one, but I realize that
others (you, Andre, etc.) may not agree.

kynn


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
gil_johnson  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 02:46
Newsgroups: comp.lang.python
From: gil_johnson <gil_john...@earthlink.net>
Date: Fri, 6 Nov 2009 18:46:33 -0800 (PST)
Local: Sat 7 Nov 2009 02:46
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 6, 6:12 am, kj <no.em...@please.post> wrote:

I don't have the code with me, but for huge arrays, I have used
something like:

>>> arr[0] = initializer
>>> for i in range N:
>>>      arr.extend(arr)

This doubles the array every time through the loop, and you can add
the powers of 2 to get the desired result.
Gil

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
r  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 03:06
Newsgroups: comp.lang.python
From: r <rt8...@gmail.com>
Date: Fri, 6 Nov 2009 19:06:29 -0800 (PST)
Local: Sat 7 Nov 2009 03:06
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 6, 6:12 am, kj <no.em...@please.post> wrote:

You mean sum'in like dis?

class PerlishList(list):
    '''Hand holding list object for even the most demanding Perl
hacker'''
    def __init__(self, dim=0):
        list.__init__(self)
        if dim:
            self.__setitem__(dim, None)

    def __setitem__(self, idx, v):
        lenkeys = len(self)
        sup = super(PerlishList, self)
        if idx > lenkeys:
            for idx in range(lenkeys, idx):
                sup.append(None)
        sup.__setitem__(idx, v)

    def __getitem__(self, idx):
        return self[idx]

l = PerlishList(3)
l.append('a')
l.append('b')
print l
l[10] = 10
print l

;-)


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Steven D'Aprano  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 15:07
Newsgroups: comp.lang.python
From: Steven D'Aprano <st...@REMOVE-THIS-cybersource.com.au>
Date: 07 Nov 2009 15:07:15 GMT
Local: Sat 7 Nov 2009 15:07
Subject: Re: Most efficient way to "pre-grow" a list?

On Fri, 06 Nov 2009 18:46:33 -0800, gil_johnson wrote:
> I don't have the code with me, but for huge arrays, I have used
> something like:

>>>> arr[0] = initializer
>>>> for i in range N:
>>>>      arr.extend(arr)

> This doubles the array every time through the loop, and you can add the
> powers of 2 to get the desired result. Gil

Why is it better to grow the list piecemeal instead of just allocating a
list the size you want in one go?

arr = [x]*size_wanted

--
Steven


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Bruno Desthuilliers  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 17:55
Newsgroups: comp.lang.python
From: Bruno Desthuilliers <bdesth.quelquech...@free.quelquepart.fr>
Date: Sat, 07 Nov 2009 18:55:14 +0100
Local: Sat 7 Nov 2009 17:55
Subject: Re: Most efficient way to "pre-grow" a list?
kj a écrit :

> As I said, this is considered an optimization, at least in Perl,
> because it lets the interpreter allocate all the required memory
> in one fell swoop, instead of having to reallocate it repeatedly
> as the array grows.

IIRC, CPython has it's own way to optimize list growth.

>  (Of course, like with all optimizations,
> whether it's worth the bother is another question.)

My very humble opinion is that unless you spot a bottleneck (that is,
you have real performance issues AND the profiler identified list growth
as the culprit), the answer is a clear and obvious NO.

> Another situation where one may want to do this is if one needs to
> initialize a non-sparse array in a non-sequential order,

Then use a dict.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luis Alberto Zarrabeitia Gomez  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 19:25
Newsgroups: comp.lang.python
From: Luis Alberto Zarrabeitia Gomez <ky...@uh.cu>
Date: Sat, 07 Nov 2009 14:25:19 -0500
Local: Sat 7 Nov 2009 19:25
Subject: Re: Most efficient way to "pre-grow" a list?

Quoting Bruno Desthuilliers <bdesth.quelquech...@free.quelquepart.fr>:

> > Another situation where one may want to do this is if one needs to
> > initialize a non-sparse array in a non-sequential order,

> Then use a dict.

Ok, he has a dict.

Now what? He needs a non-sparse array.

--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie

--
Participe en Universidad 2010, del 8 al 12 de febrero de 2010
La Habana, Cuba
http://www.universidad2010.cu


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Andre Engels  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 19:33
Newsgroups: comp.lang.python
From: Andre Engels <andreeng...@gmail.com>
Date: Sat, 7 Nov 2009 20:33:29 +0100
Local: Sat 7 Nov 2009 19:33
Subject: Re: Most efficient way to "pre-grow" a list?
On Sat, Nov 7, 2009 at 8:25 PM, Luis Alberto Zarrabeitia Gomez

<ky...@uh.cu> wrote:

> Quoting Bruno Desthuilliers <bdesth.quelquech...@free.quelquepart.fr>:

>> > Another situation where one may want to do this is if one needs to
>> > initialize a non-sparse array in a non-sequential order,

>> Then use a dict.

> Ok, he has a dict.

> Now what? He needs a non-sparse array.

Let d be your dict.

Call the zeroeth place in your array d[0], the first d[1], the 10000th
d[100000].

--
André Engels, andreeng...@gmail.com


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Luis Alberto Zarrabeitia Gomez  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 20:40
Newsgroups: comp.lang.python
From: Luis Alberto Zarrabeitia Gomez <ky...@uh.cu>
Date: Sat, 07 Nov 2009 15:40:02 -0500
Local: Sat 7 Nov 2009 20:40
Subject: Re: Most efficient way to "pre-grow" a list?

Quoting Andre Engels <andreeng...@gmail.com>:

> On Sat, Nov 7, 2009 at 8:25 PM, Luis Alberto Zarrabeitia Gomez
> <ky...@uh.cu> wrote:

> > Ok, he has a dict.

> > Now what? He needs a non-sparse array.

> Let d be your dict.

> Call the zeroeth place in your array d[0], the first d[1], the 10000th
> d[100000].

Following that reasoning, we could get rid of lists and arrays altogether.

Here's why that wouldn't work:

for x,y in zip(d,other):
    ... do something ...

Yes, we could also ignore zip and just use range/xrange to iterate for the
indices...

Lists and dictionaries have different semantics. One thing is to argue that you
shouldn't be thinking on pre-growing a list for performance reasons before being
sure that it is a bottleneck, and a very different one is to argue that because
one operation (__setitem__) is the same with both structures, we should not use
lists for what may need, depending on the problem, list semantics.

¿Have you ever tried to read list/matrix that you know it is not sparse, but you
don't know the size, and it may not be in order? A "grow-able" array would just
be the right thing to use - currently I have to settle with either hacking
together my own grow-able array, or preloading the data into a dict, growing a
list with the [0]*size trick, and updating that list. Not hard, not worthy of a
PEP, but certainly not so easy to dismiss.

--
Luis Zarrabeitia
Facultad de Matemática y Computación, UH
http://profesores.matcom.uh.cu/~kyrie

--
Participe en Universidad 2010, del 8 al 12 de febrero de 2010
La Habana, Cuba
http://www.universidad2010.cu


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Terry Reedy  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:19
Newsgroups: comp.lang.python
From: Terry Reedy <tjre...@udel.edu>
Date: Sat, 07 Nov 2009 17:19:20 -0500
Local: Sat 7 Nov 2009 22:19
Subject: Re: Most efficient way to "pre-grow" a list?

Steven D'Aprano wrote:
> On Fri, 06 Nov 2009 18:46:33 -0800, gil_johnson wrote:

>> I don't have the code with me, but for huge arrays, I have used
>> something like:

>>>>> arr[0] = initializer
>>>>> for i in range N:
>>>>>      arr.extend(arr)
>> This doubles the array every time through the loop, and you can add the
>> powers of 2 to get the desired result. Gil

> Why is it better to grow the list piecemeal instead of just allocating a
> list the size you want in one go?

It isn't.

> arr = [x]*size_wanted

Is what I would do.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Ivan Illarionov  
View profile   Translate to Translated (View Original)
 More options 7 Nov, 22:24
Newsgroups: comp.lang.python
From: Ivan Illarionov <ivan.illario...@gmail.com>
Date: Sat, 7 Nov 2009 14:24:15 -0800 (PST)
Local: Sat 7 Nov 2009 22:24
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 6, 3:12 pm, kj <no.em...@please.post> wrote:

> The best I can come up with is this:

> arr = [None] * 1000000

> Is this the most efficient way to achieve this result?

It is the most efficient SAFE way to achieve this result.

In fact, there IS the more efficient way, but it's dangerous, unsafe,
unpythonic and plain evil:

>>> import ctypes
>>> ctypes.pythonapi.PyList_New.restype = ctypes.py_object
>>> ctypes.pythonapi.PyList_New(100)

-- Ivan

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
kj  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 00:23
Newsgroups: comp.lang.python
From: kj <no.em...@please.post>
Date: Sun, 8 Nov 2009 00:23:18 +0000 (UTC)
Local: Sun 8 Nov 2009 00:23
Subject: Re: Most efficient way to "pre-grow" a list?
In <mailman.44.1257626420.2873.python-l...@python.org> Luis Alberto Zarrabeitia Gomez <ky...@uh.cu> writes:

Thanks.  Well said.

Saludos,

kynn


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
sturlamolden  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 01:03
Newsgroups: comp.lang.python
From: sturlamolden <sturlamol...@yahoo.no>
Date: Sat, 7 Nov 2009 17:03:37 -0800 (PST)
Local: Sun 8 Nov 2009 01:03
Subject: Re: Most efficient way to "pre-grow" a list?
On 6 Nov, 13:12, kj <no.em...@please.post> wrote:

> The best I can come up with is this:

> arr = [None] * 1000000

> Is this the most efficient way to achieve this result?

Yes, but why would you want to? Appending to a Python list has
amortized O(1) complexity. I am not sure about Perl, but in MATLAB
arrays are preallocated because resize has complexity O(n), instead of
amortized O(1). You don't need to worry about that in Python. Python
lists are resized with empty slots at the end, in proportion to the
size of the list. On average, this has the same complexity as pre-
allocation.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
sturlamolden  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 01:05
Newsgroups: comp.lang.python
From: sturlamolden <sturlamol...@yahoo.no>
Date: Sat, 7 Nov 2009 17:05:53 -0800 (PST)
Local: Sun 8 Nov 2009 01:05
Subject: Re: Most efficient way to "pre-grow" a list?
On 7 Nov, 03:46, gil_johnson <gil_john...@earthlink.net> wrote:>

> I don't have the code with me, but for huge arrays, I have used
> something like:

> >>> arr[0] = initializer
> >>> for i in range N:
> >>>      arr.extend(arr)

> This doubles the array every time through the loop, and you can add
> the powers of 2 to get the desired result.
> Gil

You should really use append instead of extend. The above code is O
(N**2), with append it becomes O(N) on average.

    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
sturlamolden  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 01:13
Newsgroups: comp.lang.python
From: sturlamolden <sturlamol...@yahoo.no>
Date: Sat, 7 Nov 2009 17:13:07 -0800 (PST)
Local: Sun 8 Nov 2009 01:13
Subject: Re: Most efficient way to "pre-grow" a list?
On 6 Nov, 22:03, kj <no.em...@please.post> wrote:

> As I said, this is considered an optimization, at least in Perl,
> because it lets the interpreter allocate all the required memory
> in one fell swoop, instead of having to reallocate it repeatedly
> as the array grows.

Python does not need to reallocate repeatedly as a list grows. That is
why it's called a 'list' and not an array.

There will be empty slots at the end of a list you can append to,
without reallocating. When the list is resized, it is reallocated with
even more of these. Thus the need to reallocate becomes more and more
rare as the list grows, and on average the complexity of appending is
just O(1).


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Carl Banks  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 01:18
Newsgroups: comp.lang.python
From: Carl Banks <pavlovevide...@gmail.com>
Date: Sat, 7 Nov 2009 17:18:38 -0800 (PST)
Local: Sun 8 Nov 2009 01:18
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 7, 5:05 pm, sturlamolden <sturlamol...@yahoo.no> wrote:

> On 7 Nov, 03:46, gil_johnson <gil_john...@earthlink.net> wrote:>

> > I don't have the code with me, but for huge arrays, I have used
> > something like:

> > >>> arr[0] = initializer
> > >>> for i in range N:
> > >>>      arr.extend(arr)

> > This doubles the array every time through the loop, and you can add
> > the powers of 2 to get the desired result.
> > Gil

> You should really use append instead of extend. The above code is O
> (N**2), with append it becomes O(N) on average.

I think the top one is O(N log N), and I'm suspicious that it's even
possible to grow a list in less than O(N log N) time without knowing
the final size in advance.  Citation?  Futhermore why would it matter
to use extend instead of append; I'd assume extend uses the same
growth algorithm.  (Although in this case since the extend doubles the
size of the list it most likely reallocates after each call.)

[None]*N is linear time and is better than growing the list using
append or extend.

Carl Banks


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
exar...@twistedmatrix.com  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 01:32
Newsgroups: comp.lang.python
From: exar...@twistedmatrix.com
Date: Sun, 08 Nov 2009 01:32:30 -0000
Local: Sun 8 Nov 2009 01:32
Subject: Re: Most efficient way to "pre-grow" a list?
On 01:18 am, pavlovevide...@gmail.com wrote:

The wikipedia page for http://en.wikipedia.org/wiki/Amortized_analysis
conveniently uses exactly this example to explain the concept of
amortized costs.

Jean-Paul


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Paul Rudin  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 07:07
Newsgroups: comp.lang.python
From: Paul Rudin <paul.nos...@rudin.co.uk>
Date: Sun, 08 Nov 2009 07:07:25 +0000
Local: Sun 8 Nov 2009 07:07
Subject: Re: Most efficient way to "pre-grow" a list?

kj <no.em...@please.post> writes:
> The best I can come up with is this:

> arr = [None] * 1000000

> Is this the most efficient way to achieve this result?

Depends on what you take as given. You can do it with ctypes more
efficiently, but you can also shoot yourself in the foot.

Another possibility is to use a numpy array.


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
gil_johnson  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 13:08
Newsgroups: comp.lang.python
From: gil_johnson <gil_john...@earthlink.net>
Date: Sun, 8 Nov 2009 05:08:35 -0800 (PST)
Local: Sun 8 Nov 2009 13:08
Subject: Re: Most efficient way to "pre-grow" a list?
On Nov 6, 8:46 pm, gil_johnson <gil_john...@earthlink.net> wrote:

> I don't have the code with me, but for huge arrays, I have used
> something like:

> >>> arr[0] = initializer
> >>> for i in range N:
> >>>      arr.extend(arr)

> This doubles the array every time through the loop, and you can add
> the powers of 2 to get the desired result.
> Gil

To all who asked about my previous post,

I'm sorry I posted such a cryptic note before, I should have waited
until I had the code available.

I am still new to Python, and I couldn't find a way to create an array
of size N, with each member initialized to a given value. If there is
one, please let me know.

I think Paul Rubin and Paul Rudin are right, if they really are 2
different people, an array is a better solution if you're dealing with
integers. They both mention numpy, which I know nothing about, or the
array module.

kj, what *are* you going to do with this list/array? As others have
pointed out, there are differences between lists, arrays, and
dictionaries.

The problem I was solving was this: I wanted an array of 32-bit
integers to be used as a bit array, and I wanted it initialized with
all bits set, that is, each member of the array had to be set to
4294967295. Of course, you could set your initializer to 0, or any
other 32-bit number.

Originally I found that the doubling method I wrote about before was a
LOT faster than appending the elements one at a time, and tonight I
tried the "list = initializer * N" method. Running the code below, the
doubling method is still fastest, at least on my system.

Of course, as long as you avoid the 'one at a time' method, we're
talking about fractions of a second, even for arrays that I think are
huge, like the 536,870,912 byte beastie below.

[code]

# Written in Python 3.x

import array
import time

#* * * * * * * * * * * * * * * * * * * * * *
# Doubling method, run time = 0.413938045502

t0 = time.time()

newArray = array.array('I')             # 32-bit unsigned
integers

newArray.append(4294967295)

for i in range(27):             # 2**27 integers, 2**29 bytes
    newArray.extend(newArray)

print(time.time() - t0)

print(newArray[134217727]) # confirm array is fully initialized

#* * * * * * * * * * * * * * * * * * * * * *
# One at a time, run time = 28.5479729176

t0 = time.time()

newArray2 = array.array('I')

for i in range(134217728):        # the same size as above
    newArray2.append(4294967295)

print(time.time() - t0)

print(newArray2[134217727])                   # confirm array

#* * * * * * * * * * * * * * * * * * * * * *
# List with "*", run time = 1.06160402298

t0 = time.time()

newList = [4294967295] * 134217728

print(time.time() - t0)

print(newList[134217727])                      # confirm list

[/code]

If, instead of 134,217,728 integers, I want something different, like
100,000,000, the method I use is:

[code]

#* * * * * * * * * * * * * * * * * * * * * *
# Not a power of 2, run time = 0.752086162567

t0 = time.time()

newArray = array.array('I')

tempArray = array.array('I')

tempArray.append(4294967295)

size = 100000000

while size:                                          # chew through
'size' until it's gone
    if (size & 1):                                    # if this bit of
'size' is 1
        newArray.extend(tempArray)    # add a copy of the temp array
    size >>= 1                                    # chew off one bit
    tempArray.extend(tempArray)       # double the size of the temp
array

print(time.time() - t0)

print(newArray[99999999])

#* * * * * * * * * * * * * * * * * * * * * *
# # Not a power of 2, list with "*", run time = 1.19271993637

t0 = time.time()

newList = [4294967295] * 100000000

print(time.time() - t0)

print(newList[99999999])

[/code]

I think it is interesting that the shorter list takes longer than the
one that is a power of 2 in length. I think this may say that the
"list = initializer * N" method uses something similar to the doubling
method.

Also, tempArray (above) gets reallocated frequently, and demonstrates
that reallocation is not a big problem.

Finally, I just looked into calling C functions, and found
PyMem_Malloc, PyMem_Realloc, PyMem_Free, etc. in the Memory Management
section of the Python/C API Reference Manual. This gives you
uninitialized memory, and should be really fast, but it's 6:45 AM
here, and I don't have the energy to try it.

Gil


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
gb345  
View profile   Translate to Translated (View Original)
 More options 8 Nov, 15:20
Newsgroups: comp.lang.python
From: gb345 <gb...@invalid.com>
Date: Sun, 8 Nov 2009 15:20:42 +0000 (UTC)
Local: Sun 8 Nov 2009 15:20
Subject: Re: Most efficient way to "pre-grow" a list?
In <mailman.44.1257626420.2873.python-l...@python.org> Luis Alberto Zarrabeitia Gomez <ky...@uh.cu> writes:

>¿Have you ever tried to read list/matrix that you know it is not sparse, but you

jdon't know the size, and it may not be in order? A "grow-able" array would just

>be the right thing to use - currently I have to settle with either hacking
>together my own grow-able array, or...
>...Not hard, not worthy of a
>PEP, but certainly not so easy to dismiss.

I'm pretty new to Python, and I thought I'd give this a try:

class array(list):
    """A list that grows as needed upon assignment.

    Any required padding is done with the value of the fill option.

    Attempts to retrieve an index greater than the maximum assigned
    index still produces an IndexError.
    """

    def __init__(self, seq='', fill=None):
        super(array, self).__init__(seq)
        self.fill = fill

    @property
    def max(self):
        return len(self) - 1

    def __setitem__(self, index, item):
        m = self.max
        while m < index:
            self.append(self.fill)
            m += 1
        super(array, self).__setitem__(index, item)

if __name__ == '__main__':
    x = array(('zero',))
    x[3] = 'it works!'
    print x

---------------------------------------------------------------------------
['zero', None, None, 'it works!']

Looks like it works, but it seems almost too easy.  Did I miss
anything?  Comments welcome.  (E.g.  I'm not sure that '' is the
best choice of default value for the seq parameter to __init__.)

Thanks in advance,

Gabe


    Reply    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 1 - 25 of 30   Newer >
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google