Simple question about Python lists

E

Eric

I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of
them how do I select them out. In MATLAB, if I just want the first,
fifth and eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

Thanks,

Eric
 
M

Marc 'BlackJack' Rintsch

I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of them
how do I select them out. In MATLAB, if I just want the first, fifth and
eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

b = [a for i in [1, 5, 8]]

Ciao,
Marc 'BlackJack' Rintsch
 
G

Guilherme Polo

I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of
them how do I select them out. In MATLAB, if I just want the first,
fifth and eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

MATLAB works with 1-based index, while Python is 0-based, so accessing
the index number 8 wouldn't be valid with 8 elements here in Python.

Now, to solve your problem you could either use the already suggested
answer above mine or depending on what you what else you wanna do, you
will feel more comfortable using numpy.

Supposing you have a array with 8 elements: x = numpy.arange(8)
To pull out the first, fifth and eighth elements you would do:
x[numpy.array([0, 4, 7])]

It is so no natural as it was in MATLAB, but well, it was a different language.
 
R

Robert Kern

Guilherme said:
I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of
them how do I select them out. In MATLAB, if I just want the first,
fifth and eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

MATLAB works with 1-based index, while Python is 0-based, so accessing
the index number 8 wouldn't be valid with 8 elements here in Python.

Now, to solve your problem you could either use the already suggested
answer above mine or depending on what you what else you wanna do, you
will feel more comfortable using numpy.

Supposing you have a array with 8 elements: x = numpy.arange(8)
To pull out the first, fifth and eighth elements you would do:
x[numpy.array([0, 4, 7])]

Actually, x[[0,4,7]] will work just as well.

--
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
 
E

Eric

I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of them
how do I select them out. In MATLAB, if I just want the first, fifth and
eighth element I might do something like this:
b = a([1 5 8]);
I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

b = [a for i in [1, 5, 8]]

Ciao,
        Marc 'BlackJack' Rintsch


Thanks! It makes sense, but in this case MATLAB seems easier and no
less readable. That said, I know better than for a newbie like me to
question syntax issues.

Regards,

Eric
 
R

Robert Kern

Eric said:
I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of them
how do I select them out. In MATLAB, if I just want the first, fifth and
eighth element I might do something like this:
b = a([1 5 8]);
I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?
b = [a for i in [1, 5, 8]]

Ciao,
Marc 'BlackJack' Rintsch


Thanks! It makes sense, but in this case MATLAB seems easier and no
less readable. That said, I know better than for a newbie like me to
question syntax issues.


In my experience, I never do this with lists so there's no optimized syntax for
it. I do use it very often with numpy arrays, and that does have optimized syntax.

--
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
 
S

Steven D'Aprano

Eric said:
I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of
them how do I select them out. In MATLAB, if I just want the first,
fifth and eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?

Yes: the above code uses magic numbers which convey no semantic meaning,
and should instead use *named* elemets of a container. In Python, that's
done with a mapping type, which has the built-in type of ‘dict’.

In other words: a list is best for sequences where any item is
semantically identical to any other, and you can (for example) re-order
all the elements in the list without changing their semantic meaning.
If, instead, you want semantic meaning, that's best done via *names*,
not magic numbers.


While I see your point, and in practice there are circumstance where I
would agree with you, I don't agree in general.

What the OP is asking for is a generalization of slicing. Slices already
take a stride:

alist = range(20)
alist[2:17:3]
[2, 5, 8, 11, 14]

Given a slice alist[start:end:stride] the indices are given by the
sequence start+i*stride, bounded by end. It seems to me that the OP has
asked how to take a slice where the indices are from an arbitrary set,
possibly given by an equation, but not necessarily. No practical examples
come to mind just off the top of my head, but given that the OP is coming
from a Matlab background, I bet they involve some pretty hairy maths.

Hmmm... let's see now...

http://en.wikipedia.org/wiki/Series_(mathematics)
#Summations_over_arbitrary_index_sets

To put it another way... suppose you have a sequence S given by a list,
and a set of indexes I (perhaps given by a tuple or a set), and you want
to sum the terms of S at those indexes, which mathematicians apparently
have good reason for doing, then you might write in Python:

sum(S for i in I)

But if there was slicing support for arbitrary indexes, you could write:

sum(S)

which is apparently what Matlab allows. Standard lists don't support this
slicing generalization, but numpy arrays do.
 
R

Robert Kern

Steven said:
Eric said:
I'm learning Python (while coming from MATLAB). One question I have is
that if I have a list with say 8 elements, and I want just a few of
them how do I select them out. In MATLAB, if I just want the first,
fifth and eighth element I might do something like this:

b = a([1 5 8]);

I can't seem to figure out a similar Python construct for selecting
specific indices. Any suggestions?
Yes: the above code uses magic numbers which convey no semantic meaning,
and should instead use *named* elemets of a container. In Python, that's
done with a mapping type, which has the built-in type of ‘dict’.

In other words: a list is best for sequences where any item is
semantically identical to any other, and you can (for example) re-order
all the elements in the list without changing their semantic meaning.
If, instead, you want semantic meaning, that's best done via *names*,
not magic numbers.


While I see your point, and in practice there are circumstance where I
would agree with you, I don't agree in general.

What the OP is asking for is a generalization of slicing. Slices already
take a stride:

alist = range(20)
alist[2:17:3]
[2, 5, 8, 11, 14]

Given a slice alist[start:end:stride] the indices are given by the
sequence start+i*stride, bounded by end. It seems to me that the OP has
asked how to take a slice where the indices are from an arbitrary set,
possibly given by an equation, but not necessarily. No practical examples
come to mind just off the top of my head, but given that the OP is coming
from a Matlab background, I bet they involve some pretty hairy maths.

Hmmm... let's see now...

http://en.wikipedia.org/wiki/Series_(mathematics)
#Summations_over_arbitrary_index_sets

To put it another way... suppose you have a sequence S given by a list,
and a set of indexes I (perhaps given by a tuple or a set), and you want
to sum the terms of S at those indexes, which mathematicians apparently
have good reason for doing, then you might write in Python:

sum(S for i in I)

But if there was slicing support for arbitrary indexes, you could write:

sum(S)

which is apparently what Matlab allows. Standard lists don't support this
slicing generalization, but numpy arrays do.


It's also worth noting that using a literal list is pretty rare. Usually the
index array/list comes from some other computation. The OP was just trying to be
describe the feature he wanted; that's not always the same thing as the use case
that drives the feature.

--
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
 
E

Eric

Steven D'Aprano said:
In MATLAB, if  I just want the first, fifth  and eighth element I
might do something like this:
b = a([1 5 8]);
Yes: the above code uses magic numbers which convey no semantic
meaning, and should instead use *named* elemets of a container. In
Python, that's done with a mapping type, which has the built-in
type of ‘dict’.
In other words: a list is best for sequences where any item is
semantically identical to any other, and you can (for example)
re-order all the elements in the list without changing their
semantic meaning. If, instead, you want semantic meaning, that's
best done via *names*, not magic numbers.
What the OP is asking for is a generalization of slicing.

I don't think so. (The OP is, of course, welcome to respond to
this or existing requests for clarification of their intent.)
Given a slice alist[start:end:stride] the indices are given by the
sequence start+i*stride, bounded by end. It seems to me that the OP
has asked how to take a slice where the indices are from an
arbitrary set, possibly given by an equation, but not necessarily.

I think that's exactly what is *not* being asked for, based on the
specific example given. The example was “I just want the first,
fifth, and eighth element”, and the example implementation showed
them with those numeric literals in the code. On that basis I
interpreted the need for *those elements specifically*, for some
semantic reason not yet disclosed.

If, instead, the OP wanted to retrieve “indices … from an arbitrary
set, possibly given by an equation”, I would recommend that *that
equation* be abstracted behind an expression, or even a well-named
function, that would make explicit what the *meaning* of the set was.

I maintain that anything which expresses “retrieve the indices at
these numbers” without saying *in the code* what the meaning of those
numbers is, is to be deprecated in favour of an implementation that
makes the semantic meaning explicit.

And no, before anyone suggests it, an explanatory comment is not
sufficient for this condition: the names and types used should make
clear what the meaning of the expression is. A comment saying *why* is
always appreciated; but if the comment needs to tell me *what* the
code is doing or *how*, the code instead needs to be re-written to be
explicit.

--
 \      “Saying that Java is nice because it works on all OSes is like |
  `\     saying that anal sex is nice because it works on all genders” |
_o__)                                                —http://bash.org/|
Ben Finney

Thanks much for the interesting discussion. In case anyone wonders
what problem I was trying to solve in the first case, I was simply
parsing a large text file. I read in each line, searched for the key
text using line.find('search text') and if I found the text I was
looking for, parsed the line with a=line.split(' ') since there was
only spaces breaking up parts of the line. This provided a list "a"
from which I only wanted certain elements. I wanted to select just
those elements in a particular order and then join them as a comma
delimited string to output to a second file. This is why I wanted to
select only certain items in the list and generally in a non-
consecutive order. I think the original suggestion is probably the
best one:

b = [a for i in [1, 5, 8]]

I understand the basic Python concept that there should be one obvious
way of doing something, so if there is a easier and better approach to
parsing text files (which I end up doing a lot of), feel free to
suggest it.

Thanks,

Eric
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top