Discussion: Introducing new operators for matrix computation

Gareth McCaughan gjm11 at g.local
Tue Jul 18 16:04:44 EDT 2000


Paul Prescod wrote:

[I said:]
>> Only if you implement matrices as lists of lists, in which
>> case operations like * and / won't work anyway. I was assuming
>> that (1) you have a special Matrix class, and (2) the machinery
>> for list comprehensions is flexible enough to let it express
>> other kinds of mapping.
> 
> Today, the list comprehension syntax is syntactic sugar for
> 
> a=[]
> for i in firstloop:
> 	for j in secondloop: ...
> 		a.append( i, j )
> 
> I don't see any easy way to guess what type you want as "output" so it
> has to default to a fixed type. You could of course do this:
> 
> Matrix( [...] )
> 
> I would be curious about ideas for allowing the output object to be
> specified or inferred. What would the protocol be?

Well, I was making a broken assumption about the meaning of
multiple comprehension indices: namely, that
  [(i,j) for i in [1,2], j in [1,2]]
would evaluate to [(1,1), (2,2)] rather than [(1,1), (1,2), (2,1), (2,2)].
If it's supposed to go the other way, then some of my other
assumptions stop working. :-)

However: I had been thinking along the following lines.
[expr for var in val] should produce something of the same
type as val, with the property that result[i] == expr(val[i])
for each legal index i. (Or something of the sort.)

One way to make this doable would be for each collection type
to define a "list-of-all-valid-indices" method, which (e.g.)
would return something like [0,1,2] for ["foo",23,[]]. Then
list comprehension could iterate over the result of that.
There'd also need to be a "make something new of the same
shape" method. (A "shallow copy" method would, of course,
do this just fine.)

So [f(x) for x in collection] would turn into something like

    indices = collection.valid_indices()
    result  = collection.clone()
    for index in indices:
      result[index] = f(collection[index])

There might be a more efficient way to do this, of course.

With more than one collection being iterated over, as in
[blah blah blah for x in xs, y in ys], the simplest thing
would be to use the first collection mentioned as template
and source of valid indices. (This is the thing that fails
totally if we're doing cartesian products rather than parallel
iteration.)

-- 
Gareth McCaughan  Gareth.McCaughan at pobox.com
sig under construction



More information about the Python-list mailing list