0

In trying to select the first (when counting from zero) column in a 2D 4x4 array, I wrote the following script:

import numpy
a4x4=[list(range(4*i,4*(i+1))) for i in list(range(4))]
print(a4x4)
print(a4x4[:,1])

The array seems to be alright:

[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]

but instead of

[1, 5, 9, 13]

for the second print, I get this error:

TypeError: list indices must be integers, not tuple

Why does this error appear, what is going wrong?

3
  • As a side note, you don't need those extra list calls. for i in list(range(4)) will give you the exact same results as just for i in range(4), except that it will waste time and memory building a list with the same elements as the range that you already had. Commented Sep 17, 2014 at 18:08
  • Ah, thanks. I remember the list() was a remnant of an attempt to print that range. Commented Sep 17, 2014 at 18:11
  • Just making sure. A lot of people don't get that much of Python is built around generic iterables, and there's nothing really special about lists; things like ranges, strings, files, etc. are just as iterable. (Numpy, on the other hand, is not built around iteration, but around casting operations over entire arrays or slices at once.) Commented Sep 17, 2014 at 19:58

2 Answers 2

3

You've import numpy but you aren't using it. What you have instead is a list of lists, and Python doesn't support multidimensional slicing for that (ie, you'd need [a4x4[i][1] for i in range(4)] to get the result you expect, but really you should be using numpy). Here's an example:

import numpy
a4x4=numpy.array([list(range(4*i,4*(i+1))) for i in list(range(4))])
print(a4x4)
print(a4x4[:,1])

By the way, in numpy you can also build the array you want directly, like this:

 numpy.arange(4*4).reshape((4,4))

(And also in Python one doesn't need the list calls I have above, I'm just trying to keep the code as similar to yours as possible to see the key thing, which is converting the list of lists into a numpy array.)

Sign up to request clarification or add additional context in comments.

3 Comments

Perfect, I had no idea that slicing would only work on numpy arrays. Why that difference between lists of lists and arrays?
@Betohaku: slicing works on both numpy arrays and lists; it's just that multidimensional slicing only works on numpy arrays.
@Betohaku: There are a lot of differences. Arrays support multidimensional slicing, data sharing between slices, element-wise operators, and a whole slew of powerful methods, and take less memory for storage and less time for many operations. Lists of lists support heterogeneous values, support "jagged" arrays (rows can be different lengths), interoperate more easily with iterable-based programming, and don't require a third-party library. The numpy intro docs explain things in more detail.
1

You can produce the result you want using list comprehension - just as you created the original 4x4:

a4x4=[list(range(4*i,4*(i+1))) for i in list(range(4))]
print([a4x4[i][1] for i in range(4)])

furthermore, you can simplify your logic a bit by tossing out the list function:

a4x4 = [range(4*i,4*(i+1)) for i in range(4)]
print([a4x4[i][1] for i in range(4)])

2 Comments

An intuitive approach indeed, but this seems like quite a roundabout, especially since it requires you to know the dimensions of the array (which of course in this example you do, but imagine the use outside this context).
+1 since this answer made my realize a mistake in my own, but still, I think the OP wants to be using numpy instead of list comprehensions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.