Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > python2.4 generator expression > python2.3 list expression

Reply
Thread Tools

python2.4 generator expression > python2.3 list expression

 
 
snacktime
Guest
Posts: n/a
 
      02-21-2005
I need to convert a generator expression to a list expression so it
will work under python 2.3.

I rewrote this:

for c in range(12:
even_odd = (sum(bool(c & 1<<b) for b in range()) & 1

As this:

for c in range(12:
bo = [bool(c & 1<<b) for b in range(]
even_odd = sum(bo) & 1


Seems to work, is there a better way to do this?
 
Reply With Quote
 
 
 
 
Steven Bethard
Guest
Posts: n/a
 
      02-21-2005
snacktime wrote:
> I need to convert a generator expression to a list expression so it
> will work under python 2.3.
>
> I rewrote this:
>
> for c in range(12:
> even_odd = (sum(bool(c & 1<<b) for b in range()) & 1
>
> As this:
>
> for c in range(12:
> bo = [bool(c & 1<<b) for b in range(]
> even_odd = sum(bo) & 1
>
> Seems to work, is there a better way to do this?


Well, if you were happy with your generator expression, you can use
almost exactly the same syntax:

for c in range(12:
even_odd = (sum([bool(c & 1<<b) for b in range(])) & 1

No need for the 'bo' variable...

STeVe
 
Reply With Quote
 
 
 
 
Michael Hoffman
Guest
Posts: n/a
 
      02-21-2005
snacktime wrote:
> I need to convert a generator expression to a list expression so it
> will work under python 2.3.
>
> I rewrote this:
>
> for c in range(12:
> even_odd = (sum(bool(c & 1<<b) for b in range()) & 1
>
> As this:
>
> for c in range(12:
> bo = [bool(c & 1<<b) for b in range(]
> even_odd = sum(bo) & 1
>
>
> Seems to work, is there a better way to do this?


If you want to keep it as a generator that doesn't build a list
in memory, you can use itertools:

import itertools

for c in range(12:
def _even_odd_func(b): return bool(c & 1<<b)
even_odd = (sum(itertools.imap(_even_odd_func, xrange())) & 1

The fact that you used range() instead of xrange() indicates that
you may not care about this, though.
--
Michael Hoffman
 
Reply With Quote
 
Peter Otten
Guest
Posts: n/a
 
      02-21-2005
snacktime wrote:

> I need to convert a generator expression to a list expression so it
> will work under python 2.3.
>
> I rewrote this:
>
> for c in range(12:
> even_odd = (sum(bool(c & 1<<b) for b in range()) & 1
>
> As this:
>
> for c in range(12:
> bo = [bool(c & 1<<b) for b in range(]
> even_odd = sum(bo) & 1
>
>
> Seems to work, is there a better way to do this?


Summing over zeros seems pointless, so

>>> for c in range(12:

.... print len([1 for b in range( if c & 1 << b]) & 1,
....
0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1
1 0 0 1 1 0 1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 0 1 1 0
1 0 0 1 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 1 1 0 1 0
0 1 0 1 1 0 0 1 1 0 1 0 0 1

The same simplification works for genexps, but you have to use sum() there
instead of len(). Another optimization would be to precalculate the
bitmasks [1 << b for b in range(] outside the loop.

Peter

 
Reply With Quote
 
Dan Sommers
Guest
Posts: n/a
 
      02-21-2005
On Sun, 20 Feb 2005 20:56:52 -0800,
snacktime <(E-Mail Removed)> wrote:

> I need to convert a generator expression to a list expression so it
> will work under python 2.3.


> I rewrote this:


> for c in range(12:
> even_odd = (sum(bool(c & 1<<b) for b in range()) & 1


> As this:


> for c in range(12:
> bo = [bool(c & 1<<b) for b in range(]
> even_odd = sum(bo) & 1



> Seems to work, is there a better way to do this?


for c in range( 128 ):
even_odd = 0
print '%3d' % c,
while c:
c &= c - 1
even_odd = not even_odd
print int( even_odd )

Okay, so your inner loop is only counting to 8, but IMO this is a good
example of how to use a better algorithm instead of optimizing the code
of a naïve one. My inner loop only iterates over 1-bits.

"Better," of course is all relative. Your algorithm obviously counts
bits in an integer. My algorithm is less clear at first glance (and
even second and third glance), but nearly idiomatic to those of us who
spent lots of time writing embedded assembly code.

If you have the space to spare, a lookup table (pre-calculated or
created during your program's initialization) is probably the best way
to go.

Regards,
Dan

--
Dan Sommers
<http://www.tombstonezero.net/dan/>
Never play leapfrog with a unicorn.
 
Reply With Quote
 
Christos TZOTZIOY Georgiou
Guest
Posts: n/a
 
      02-21-2005
On 21 Feb 2005 06:48:19 -0500, rumours say that Dan Sommers <(E-Mail Removed)>
might have written:

[snip: snacktime posts code to count bits]

>> Seems to work, is there a better way to do this?


[Dan]
>for c in range( 128 ):
> even_odd = 0
> print '%3d' % c,
> while c:
> c &= c - 1
> even_odd = not even_odd
> print int( even_odd )


Just for the sake of people who haven't messed with bit manipulation in C or
assembly, the effect of

c &= c - 1

is to reset the rightmost (less significant) '1' bit of a number (ie change it
to '0').
--
TZOTZIOY, I speak England very best.
"Be strict when sending and tolerant when receiving." (from RFC195
I really should keep that in mind when talking with people, actually...
 
Reply With Quote
 
Bryan
Guest
Posts: n/a
 
      02-21-2005
Christos TZOTZIOY Georgiou wrote:
> On 21 Feb 2005 06:48:19 -0500, rumours say that Dan Sommers <(E-Mail Removed)>
> might have written:
>
> [snip: snacktime posts code to count bits]
>
>
>>>Seems to work, is there a better way to do this?

>
>
> [Dan]
>
>>for c in range( 128 ):
>> even_odd = 0
>> print '%3d' % c,
>> while c:
>> c &= c - 1
>> even_odd = not even_odd
>> print int( even_odd )

>
>
> Just for the sake of people who haven't messed with bit manipulation in C or
> assembly, the effect of
>
> c &= c - 1
>
> is to reset the rightmost (less significant) '1' bit of a number (ie change it
> to '0').


i tried c &= c - 1 but i'm not getting the least significant or rightmost bit
reset to zero. am i misunderstanding something?

>>> 2 & 1 # 2 = 0x10; reset right most would be 0x10

0
>>> 10 & 9 # 10 = 0x1010; reset right most would be 0x1010

8

bryan

 
Reply With Quote
 
Duncan Booth
Guest
Posts: n/a
 
      02-21-2005
Bryan wrote:

>> is to reset the rightmost (less significant) '1' bit of a number (ie
>> change it to '0').

>
> i tried c &= c - 1 but i'm not getting the least significant or
> rightmost bit reset to zero. am i misunderstanding something?
>
> >>> 2 & 1 # 2 = 0x10; reset right most would be 0x10

> 0
> >>> 10 & 9 # 10 = 0x1010; reset right most would be 0x1010

> 8


The difference between the original "reset the rightmost '1' bit", and your
interpretation: "reset the rightmost bit" is the "'1'".

The rightmost bit that is set is reset. So 0x10 -> 0, and 0x1010 -> 0x1000.

If you want to extract the least significant set bit from a number 'x' you
can use (x&-x):

>>> x = 0xab4
>>> while x:

print hex(x&-x), hex(x)
x ^= (x&-x)


0x4 0xab4
0x10 0xab0
0x20 0xaa0
0x80 0xa80
0x200 0xa00
0x800 0x800
>>>


(but don't try this if x is negative: it works but never terminates).
 
Reply With Quote
 
Brian Beck
Guest
Posts: n/a
 
      02-21-2005
Duncan Booth wrote:
> The difference between the original "reset the rightmost '1' bit", and your
> interpretation: "reset the rightmost bit" is the "'1'".
>
> The rightmost bit that is set is reset. So 0x10 -> 0, and 0x1010 -> 0x1000.
>
> If you want to extract the least significant set bit from a number 'x' you
> can use (x&-x):


My interpretation of Bryan's (mis?)interpretation (heh) was that since
in the numbers 2 and 10 (as in his examples), the least significant bit
was already 0, performing an operation that set it to 0 should result in
the number unchanged. As his tests show, this is not the case. This is
because the operation works only if the least significant bit actually
NEEDS to be unset. To zero the least significant bit unconditionally, we
can use:

x &= ~1

--
Brian Beck
Adventurer of the First Order
 
Reply With Quote
 
Bryan
Guest
Posts: n/a
 
      02-21-2005
Duncan Booth wrote:
> Bryan wrote:
>
>
>>>is to reset the rightmost (less significant) '1' bit of a number (ie
>>>change it to '0').

>>
>>i tried c &= c - 1 but i'm not getting the least significant or
>>rightmost bit reset to zero. am i misunderstanding something?
>>
>>
>>>>>2 & 1 # 2 = 0x10; reset right most would be 0x10

>>
>>0
>>
>>>>>10 & 9 # 10 = 0x1010; reset right most would be 0x1010

>>
>>8

>
>
> The difference between the original "reset the rightmost '1' bit", and your
> interpretation: "reset the rightmost bit" is the "'1'".
>
> The rightmost bit that is set is reset. So 0x10 -> 0, and 0x1010 -> 0x1000.
>
> If you want to extract the least significant set bit from a number 'x' you
> can use (x&-x):
>
>
>>>>x = 0xab4
>>>>while x:

>
> print hex(x&-x), hex(x)
> x ^= (x&-x)
>
>
> 0x4 0xab4
> 0x10 0xab0
> 0x20 0xaa0
> 0x80 0xa80
> 0x200 0xa00
> 0x800 0x800
>
>
> (but don't try this if x is negative: it works but never terminates).


thanks duncan... you're right, i did intrepret this as "reset the rightmost bit"
instead of "reset the rightmost '1' bit". and i must have read what christos
wrote 100 times!!!

bryan

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
List comprehension vs generator expression memory allocation candide Python 3 09-20-2009 05:17 PM
UART with fractional baudrate generator ? Or fractional baudrate generator alone Martin Maurer VHDL 3 04-19-2006 01:26 PM
execution order in list/generator expression bonono@gmail.com Python 3 10-23-2005 09:48 AM
subtle side effect of generator/generator expression bonono@gmail.com Python 9 10-16-2005 06:42 PM
generator function within a generator function doesn't execute? TheDustbustr Python 1 07-25-2003 10:45 AM



Advertisments