From: Alain Ketterlin on 1 Aug 2010 09:59 Lawrence D'Oliveiro writes: >>> V = tuple \ >>> ( >>> x >>> / >>> l >>> for x in V >>> for l in >>> (math.sqrt(reduce(lambda a, b : a + b, (y * y for y in V), >>> 0)),) >>> ) >> >> You got the order wrong (it has to be for l ... for x ...) > > No, I deliberately put it in that order to ensure that the value for l can > only ever be evaulated once. Try this (essentially equivalent to your code): def f(): print "hello" return 1 V = tuple( 1 for x in [1,2,3] for l in (f(),) ) How many "hello"s do you see? Comprehension are not loops spelled backwards. The values in: whatever for i ... for j ... are the values produced by the equivalent code: for i ... for j ... whatever -- Alain. From: Terry Reedy on 1 Aug 2010 19:50 On 7/30/2010 7:46 AM, Lawrence D'Oliveiro wrote:> Say a vector V is a tuple of 3 numbers, not all zero. You want to normalize > it (scale all components by the same factor) so its magnitude is 1. > > The usual way is something like this: > > L = math.sqrt(V * V + V * V + V * V) > V = (V / L, V / L, V / L) > > What I donât like is having that intermediate variable L leftover after the > computation. So, instead of fooling around with error-prone, hard-to-type constructions, just delete the damn thing! def L Compare those foolproof 5 chars to what at first did not work right and even what did. And, as other said, in most real applications, you will normalize in more than one place. In fact, you may well want a vlen function. def vlen(seq): return math.sqrt(sum(x*x for x in seq)) -- Terry Jan Reedy From: Matteo Landi on 1 Aug 2010 19:56 On Mon, Aug 2, 2010 at 1:50 AM, Terry Reedy wrote:> On 7/30/2010 7:46 AM, Lawrence D'Oliveiro wrote: >> >> Say a vector V is a tuple of 3 numbers, not all zero. You want to >> normalize >> it (scale all components by the same factor) so its magnitude is 1. >> >> The usual way is something like this: >> >>     L = math.sqrt(V * V + V * V + V * V) >>     V = (V / L, V / L, V / L) >> >> What I dont like is having that intermediate variable L leftover after >> the >> computation. > > So, instead of fooling around with error-prone, hard-to-type constructions, > just delete the damn thing! > > def L del L :P > > Compare those foolproof 5 chars to what at first did not work right and even > what did.  And, as other said, in most real applications, you will normalize > in more than one place. In fact, you may well want a vlen function. > > def vlen(seq): return math.sqrt(sum(x*x for x in seq)) > > -- > Terry Jan Reedy > > > -- > http://mail.python.org/mailman/listinfo/python-list > -- Matteo Landi http://www.matteolandi.net/ From: Lawrence D'Oliveiro on 1 Aug 2010 20:41 In message <87k4oah1rp.fsf(a)dpt-info.u-strasbg.fr>, Alain Ketterlin wrote: > Lawrence D'Oliveiro writes: > >> No, I deliberately put it in that order to ensure that the value for l >> can only ever be evaulated once. > > Try this (essentially equivalent to your code): > > def f(): > print "hello" > return 1 > > V = tuple( 1 for x in [1,2,3] for l in (f(),) ) > > How many "hello"s do you see? > > Comprehension are not loops spelled backwards. The values in: > > whatever for i ... for j ... > > are the values produced by the equivalent code: > > for i ... > for j ... > whatever Damn. I thought that e for i ... for j ... was equivalent to (e for i ...) for j ... Looks like I was wrong. From: Bartc on 2 Aug 2010 05:55 "Alain Ketterlin" wrote in message news:877hkdhyl5.fsf(a)dpt-info.u-strasbg.fr...> Lawrence D'Oliveiro writes: > >> Say a vector V is a tuple of 3 numbers, not all zero. You want to >> normalize >> it (scale all components by the same factor) so its magnitude is 1. >> >> The usual way is something like this: >> >> L = math.sqrt(V * V + V * V + V * V) >> V = (V / L, V / L, V / L) > Your best bet is to define a function that does the normalization. Your > (local) name will disappear at the end of the call. If you want it to > work for any vector size: > > def norm(V): > L = math.sqrt( sum( [x**2 for x in V] ) ) > return [ x/L for x in V ] There's a cost involved in using those fancy constructions. I found the following to be about twice as fast, when vectors are known to have 3 elements: def norm3d(v): L = math.sqrt((v*v+v*v+v*v)) return (v/L,v/L,v/L) (Strangely, changing those divides to multiplies made it slower.) -- Bartc