views:

91

answers:

3

I would like to create a list like this

list = []

for i in range(150):
    list.append({'open': False, 'serve': False})

But is there a better way in Python to do it ?

+5  A: 

With a list comprehension (don't use list as a variable name, as it shadows the python built-in):

# use range() in Python 3
l = [{'open': False, 'serve': False} for i in xrange(150)]
tonfa
The difference between xrange and range is that range creates a list (in this case of 150 numbers), while xrange creates a generator (a small function that gets called 150 times). On large numbers, xrange is faster and uses a lot less memory.
gnud
On small numbers like 150 it doesn't matter.
Georg
Using `list` is fine in functions where you don't need the built-in type. It's obviously a superior name over lowercase `l`, which is frowned upon in the Python style guide because it is hard to distinguish from `1` and `I`—the guide recommends using `L` instead.
Ferdinand Beyer
I don't like shadowing keywords, ever. You forget you did it, and then your code does something unexpected and odd. Personally, I like to use "lst" as a random list name, rather than the recommended 'L', but that's just a matter of taste.
steveha
according the style guide, if you want a name that clashes with a builtin, you should be using list_ instead of list. Isn't it better to have a descriptive name like open_list or serve_list rather that renaming it later when we want to use the list builtin...
Shrikant Sharat
Heh, comment-until-end-of-line in Python is '#', not "//". :-)
steveha
Ok, thank you very much. I knew that with Python I could do it faster.
Natim
I think the style guide is written in the spirit of real programs. For this example I think l is fine even though it does look like a 1, it is used in a place where 1 would not be allowed.
gnibbler
On this computer xrange(150) takes .5 microseconds. range(150) takes 4 microseconds. If it is not in the middle of a loop i think range is better in this case as it becomes one less change when you port to python3
gnibbler
A: 

The list comprehension to build your data structure is probably slightly more efficient. It's also much much terser. Sometimes the terseness is a nice thing, and sometimes it just obscures what is going on. In this case I think the listcomp is pretty clear.

But the listcomp and the for loop both end up building exactly the same thing for you, so this is really a case where there is no "best" answer.

steveha
+1  A: 

Whatever you do, don't try list = [{'open':False,'serve':False}]*150, as you will have the same dictionary 150 times. :D

You will then get fun behavior, like

>>> list[0]['open'] = True
>>> list[1]['open'] = False
>>> print list[0]['open']
False

>>> list[0] is list[1]
True

As gs noted, tn python 2.6, you can use namedtuple, which is easier on memory:

from collections import namedtuple
Socket = namedtuple('Socket', 'open serve')
sockets = [Socket(False,False) for i in range(150)]
wisty