24

I create a 6x5 2d array, initially with just None in each cell. I then read a file and replace the Nones with data as I read them. I create the empty array first because the data is in an undefined order in the file I'm reading. My first attempt I did this:

x = [[None]*5]*6

which resulted in some weird errors that I now understand is because the * operator on lists may create references instead of copies.

Is there an easy one liner to create this empty array? I could just do some for loops and build it up, but that seems needlessly verbose for python.

Colin
  • 10,447
  • 11
  • 46
  • 54
  • 3
    If you're dealing with n-dimensional arrays, you should at least be aware that numpy exists: http://numpy.scipy.org/ There's nothing wrong with nested lists, of course, and adding a (large) dependency like numpy is not always a good thing. However, if you don't already know about it, well, now you do! – Joe Kington Nov 19 '10 at 22:42

3 Answers3

42

Using nested comprehension lists :

x = [[None for _ in range(5)] for _ in range(6)]
Vincent Savard
  • 34,979
  • 10
  • 68
  • 73
32

What's going on here is that the line

x = [[None]*5]*6

expands out to

x = [[None, None, None, None, None, None]]*6

At this point you have a list with 6 different references to the singleton None. You also have a list with a reference to the inner list as it's first and only entry. When you multiply it by 6, you are getting 5 more references to the inner list as you understand. But the point is that theres no problem with the inner list, just the outer one so there's no need to expand the construction of the inner lists out into a comprehension.

x = [[None]*5 for _ in range(6)] 

This avoids duplicating references to any lists and is about as concise as it can readably get I believe.

aaronasterling
  • 68,820
  • 20
  • 127
  • 125
1

If you aren't going the numpy route, you can fake 2D arrays with dictionaries:

>>> x = dict( ((i,j),None) for i in range(5) for j in range(6) )
>>> print x[3,4]
None
Russell Borogove
  • 18,516
  • 4
  • 43
  • 50