Mailing List Archive

A summary of answers questions
Hi,

I got a lot of helpful replies to my questions. Here is a summary of the
useful ones.

> 1) loop a known number of times, without creating a list of indexes:
>
> for i in range(N):
> # do something

use xrange(N) instead.

> 2) Is there a "case" construct?

OOPS! Sorry about this, as it turns out I found this in the FAQ an hour
or so after posting.

There were some helpful suggestions, however, including:

dispatch = {
'one':func_one,
'two':func_two,
}

func_to_call = dispatch[ switch_variable ]
func_to_call()


> 3) lists of indexes:

Using the "take" function from NumPy does just what I wanted:

from UserArray import take
new_list = take(list,indices)

Note, this returns an array, but you can convert back to a list if need
be. That would just be:

new_list = take(list,indices).tolist()

NOTE: as it happens, I was using NumPy arrays anyway, so take was just
what I'm looking for. This is so useful, however, that I'd love to see
it added to the core language.

Some other options:

new_list = map(lambda x: list[x], indexes)

Now this I like! clean, simple, and, I imagine, fast.

Here's the "obscure one-liner":

import operator
list = [1,2,3,4,5,6,7,8,9,10,11]
indices = [3,5,9]
new_list = map (operator.getitem, len (indices) * [list], indices)

This certainly works, but it builds a list that is
len(indices)*len(list) long, which could be pretty darn big, so it
doesn't seem like a very efficient way to go.


Thanks for everyone's input.

> -chris
>
> cbarker@jps.net
>
> --== Sent via Deja.com http://www.deja.com/ ==--
> ---Share what you know. Learn what you don't.---
>


--== Sent via Deja.com http://www.deja.com/ ==--
---Share what you know. Learn what you don't.---
A summary of answers questions [ In reply to ]
> Some other options:
>
> new_list = map(lambda x: list[x], indexes)
>
> Now this I like! clean, simple, and, I imagine, fast.

Yeah. But you still need a default argument or something to get a
reference to list into the lambda's namespace and make this expression
reliable. Probably the posts about it haven't percolated through to you
yet.

new_list = map (lambda x, l = list: l [x], indexes)

will do the trick.

> Here's the "obscure one-liner":
>
> import operator
> list = [1,2,3,4,5,6,7,8,9,10,11]
> indices = [3,5,9]
> new_list = map (operator.getitem, len (indices) * [list], indices)
>
> This certainly works, but it builds a list that is
> len(indices)*len(list) long, which could be pretty darn big, so it
> doesn't seem like a very efficient way to go.

It probably isn't as efficient as some of the alternatives, but not for
this reason. The expression (len (indices) * [list]) makes a list with
(len (indices)) entries, each a pointer to list. It doesn't make any extra
copies of list along the way. Which just adds to its obscurity, I
guess. :)

E.g.
>>> l = 5 * [[5]]
>>> l
[[5], [5], [5], [5], [5]]
>>> # Change "all" of these values in one fell swoop:
...
>>> l [0][0] = 6
>>> l
[[6], [6], [6], [6], [6]]

See you.
Alex.
A summary of answers questions [ In reply to ]
> ...
> Some other options:
>
> new_list = map(lambda x: list[x], indexes)
>
> Now this I like! clean, simple, and, I imagine, fast.

Likely the slowest method of all -- incurs the overhead of a Python-level
function call for every list element.

> Here's the "obscure one-liner":
>
> import operator
> list = [1,2,3,4,5,6,7,8,9,10,11]
> indices = [3,5,9]
> new_list = map (operator.getitem, len (indices) * [list], indices)
>
> This certainly works, but it builds a list that is
> len(indices)*len(list) long, which could be pretty darn big, so it
> doesn't seem like a very efficient way to go.

Much faster than the lambda -- things aren't always as they appear <wink>.
The subexpression constructs one list of length indices, each element of
which is (under the covers) a pointer to (the same) list.

This calls operator.getitem for each element in the list too, but
operator.getitem is a C function so doesn't incur the expense of calling a
Python function. That's what makes this so much faster than the lambda
version.

if-guido-had-spelled-lambda-"adbmal"-people-would-expect-it-to-
be-slow-ly y'rs - tim