but when I try to use fancy indexing to select the first item in each
list I get:
a[0][:]=[1,2,3]
a[:][0]=[1,2,3]
Why is this and is there a way to select [1,4,7]?
> I know that I can index into a list of lists like this:
> a=[[1,2,3],[4,5,6],[7,8,9]]
> a[0][2]=3
> a[2][0]=7
>
> but when I try to use fancy indexing to select the first item in each
> list I get:
Let me write out in words what you're doing, and it should become clear:
> a[0][:]=[1,2,3]
Here you're making a list of all elements of the first element of a.
> a[:][0]=[1,2,3]
>
And here you're selecting the first element of all elements of a.
Huh. Not quite as clear as I hoped. But ponder on this for a few
moments. It'll dawn on you eventually.
> Why is this and is there a way to select [1,4,7]?
zip(*a)[0]
(or rather list(zip(*a)[0]), if you definitely need a list and not a
tuple)
/W
--
INVALID? DE!
On Wed, 8 Sep 2010 15:08:11 -0400 Andreas Waldenburger
<use...@geekmail.INVALID> wrote:
> > a[0][:]=[1,2,3]
> Here you're making a list of all elements of the first element of a.
>
That is, you're making a copy of the first element of a.
> > a[:][0]=[1,2,3]
> >
> And here you're selecting the first element of all elements of a.
>
That is, you're taking the first element of a copy of a.
I hope this is a little less confusing.
/W
--
INVALID? DE!
It's not fancy indexing. It's called taking a slice of the existing
list. Look at it this way
a[0] means take the first element of a. The first element of a is [1,2,3]
a[0][:] means take all the elements in that first element of a. All
the elements of [1,2,3] are [1,2,3].
a[:] means take all the elements of a. So a[:] is [[1,2,3],[4,5,6],[7,8,9]].
a[:][0] means take the first element of all the elements of a. The
first element of a[:] is [1,2,3].
There is no simple way to get [1,4,7] because it is just a list of
lists and not an actual matrix. You have to extract the elements
yourself.
col = []
for row in a:
col.append(row[0])
You can do this in one line using a list comprehension:
[ row[0] for row in a ]
> There is no simple way to get [1,4,7] because it is just a list of
> lists and not an actual matrix. You have to extract the elements
> yourself.
>
> col = []
> for row in a:
> col.append(row[0])
>
>
> You can do this in one line using a list comprehension:
> [ row[0] for row in a ]
I would suggest this (esp. the list comprehension version) over my
suggestion of zip(). WAAAYYYY more readable. Apparently I'm getting
rusty.
/W
--
INVALID? DE!
zip is very handy for inverting rows and cols (x's and y's, whatever)
>>> a = [(1,2),(3,4),(5,6),(7,8),(9,10)]
>>> zip(*a)
[(1, 3, 5, 7, 9), (2, 4, 6, 8, 10)]
So, I like zip if you're dealing with a in a matrix-ish manner, and list
comps for picking selected items out of a list.
Emile
Now if I want to select the first item in every 2nd item of list a
(ie: [1,7]) can I use ::2 anywhere or do I need to create a list of
indices to use in a more complex for loop?
You are trying to look at a list of lists as an array and have
discovered where the asymmetry of the former makes the two
non-equivalent. To slice multi-dimensional arrays any which way, you
need an appropriate package, such as numpy.
--
Terry Jan Reedy
Yes. You could either do that, or do
[row[0] for row in a[::2]]. It doesn't make that much of a difference,
unless memory is really tight (doing the ::2 first means your list is
smaller to begin with)
> On Wed, Sep 8, 2010 at 3:18 PM, Jonno <jonnoj...@gmail.com> wrote:
> [snip]
> > Now if I want to select the first item in every 2nd item of list a
> > (ie: [1,7]) can I use ::2 anywhere or do I need to create a list of
> > indices to use in a more complex for loop?
> >
> Seems like the simplest way would be:
> [row[0] for row in a][::2]
What you're doing here is selecting every second item of the list of
first items of the items in a, not the first items of every second item
in a (head spinning yet?).
If I'm not completely mindbent right now, these are logically
equivalent, but not computationally.
Compare
[row[0] for row in a][::2] # (your Python code)
with
[row[0] for row in a[::2]] # (as per your description)
The first one is more work for your computer, because it'll pick out
the first elements of *all* of the items in a, whereas the second only
picks out the first elements of every second item in a (which is only
half the amount of "picks" compared to the former).
I just thought I'd mention it. Because it might make a difference in
one of your programs some day. And because I'm a pedant ;).
/W
--
INVALID? DE!
Thanks again. It is nice to know how to do things properly even though
in my case it probably won't make much difference.
Terry, I would have used numpy arrays (I actually use them later in
the code) except the lists in my list aren't all of the same length.
A motivating example:
[~]
|1> import numpy
[~]
|2> a = numpy.array([[1,2,3],[4,5,6],[7,8,9]])
[~]
|3> a
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
[~]
|4> a[0,2]
3
[~]
|5> a[2,0]
7
[~]
|6> a[0,:]
array([1, 2, 3])
[~]
|7> a[:,0]
array([1, 4, 7])
--
Robert Kern
"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
The fastest way to find out is probably typing at the interactive
prompt. Just jump in at the deep end and see what happens. Then wait
until someone tells you to use the timeit module.
Cheers.
Mark Lawrence.
Understood. My data actually has 2 features which make it
non-rectangular in most circumstances. One is the extra element at the
start of every nth line (I now know how to remove that) and the second
is that some lines contain more data than others. My data is
essentially a m,m,n array but data from each row is shifted to the
next line when the line is full (4 columns). A new row then starts a
new line.
I want to pick out the data and assign it to an array but I'm
wondering whether I should first try to take the data on the extra
lines, remove it and stick it on the end of the original line (the
data from one "row" could extend onto multiple lines). Or whether I'm
better trying to create the array using loops to index my way through
the lines the way they already are laid out. Hope this makes sense.