Multi-dimensional list initialization
andrew3 at r3dsolutions.com
Thu Nov 8 04:13:25 CET 2012
On 11/07/2012 03:39 PM, Ian Kelly wrote:
> Why? Just to get rid of an FAQ?
> Here's one of the more interesting uses from my own code:
OK, and is this a main use case? (I'm not saying it isn't I'm asking.)
> Replacing the list multiplication in that function with a list
> comprehension would be awkward, as the obvious replacement of
> [iter(iterable) for _ in range(n)] would produce different results.
Yes. I have a thought on that.
> How exactly do you propose to indicate to the compiler which parts of
> the expressions are meant to be cached, and which are not?
OK; Here's what I would consider a safe implementation -- but it could
be improved later.
There is a special keyword which signals the new type of comprehension;
A normal comprehension would say eg: '[ foo for i in xrange ]'; but when
the 'for i in' is reduced to a specific keyword such as 'ini' (instead
of problematic 'in') the caching form of list comprehension would start.
So, then, just like a comprehension -- the interpreter will begin to
evaluate the code from the opening bracket '['; But anything other than
a function/method will raise a type error (people might want to change
that, but it's safe).
The interpreter then caches all functions/initialiser methods it comes
into contact with.
Since every function/method has a parameter list (even if empty); The
interpreter would evaluate the parameter list on the first pass through
the comprehension, and cache each parameter list with it's respective
When the 'ini' keyword is parsed a second time, Python would then
evaluate each cached function on its cached parameter list; and the
result would be stored in the created list.
This cached execution would be repeated as many times as is needed.
Now, for your example:
> values = zip(samples, times * num_groups)
> if len(values)< len(times) * num_groups:
> # raise an error
Might be done with:
values = zip( samples, [ lambda:times, ini xrange(num_groups) ] )
if len(values) < len(times) * num_groups
The comma after the lambda is questionable, and this construction would
be slower since lambda automatically invokes the interpreter; but it's
If you could provide a built in which returns a reference to the
parameter passed to it; that would run at max system speed; by default,
all built-in object initializers are maximally fast.
The key difference is that the ini syntax evaluates the parameter lists
only once; and the ini's purpose is for repeating an initialization of
the same kind of object in multiple different places.
As an aside, how would you do the lambda inside a list comprehension?
[lambda:6 for i in xrange(10) ] # Nope.
Generic lists allow a spurrious comma, so that [ 3,3,3, ] = [3,3,3]
[lambda:6, for i in xrange(10) ] # but this is no good.
I have to do:
def ref(): return 6
[ref(x) for i in xrange(10) ]
> Of course you got an integer. You took an index of the range object,
> not a slice. The rule is that taking an index of a sequence returns an
> element; taking a slice of a sequence returns a sub-sequence. You
> still have not shown any inconsistency here.
Because it's an arbitrary rule which operates differently than the
traditional idea shown in python docs?
slice.indices() is *for* (QUOTE)"representing the _set of indices_
specified by _range_(start, stop, step)"
There are examples of python doing this; use Google... They use slice
indices() to convert negative indexes into positive ones _compatible
some_getitem_method_in_a_subclass_foo( self, range ):
for i in xrange( range.indices( len(self) ) ):
ret.append( self.thing[i] )
The return is equivalent to a range object in the sense that it is an
iterator object, but it's not the same iterator object. It will still
work with legacy code.... since different iterators can be interchanged
so long as they return the same values.
> No, he wasn't. He was talking about multiplying lists of dicts, and
> whether the dicts are then copied or not, just like every other Q&A
> item in that dialogue was concerning whether item X in a list should
> expect to be copied when the containing list is multiplied.
I already told him several times before that what the answer was;
It doesn't copy anything except the list itself.
Then he asks, "does it multiply dicts" and no mention of it being inside
He's browbeating a dead horse.
> Perhaps you're not aware that on the Internet, TYPING IN ALL CAPS is
> commonly construed as SHOUTING.
Sure, and people say:
THIS IS YELLING, AND I AM DOING IT HERE AS AN EXAMPLE.
This is STRESS.
This is SHOCK!
I don't recall typing any _full sentence_ in all caps, if I did, I'm
awfully sorry. I didn't mean it.
Yes, he is beginning to get condescendingly exasperating. Everyone else
seems to understand 85+% of what I say, correctly. He doesn't; and now
replying to him appears to confuse everyone else.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-list