Dumb python questions

Bengt Richter bokr at accessone.com
Sun Aug 19 02:06:18 CEST 2001


On 18 Aug 2001 12:43:29 -0700, Paul Rubin <phr-n2001 at nightsong.com> wrote:

>m.faassen at vet.uu.nl (Martijn Faassen) writes:
>> > I think I'm reacting not as much to language differences as to
>> > differences in system maturity.  Whenever I write something in Perl or
>> > CL, and I need to do something like turn an array into a string,
>> 
>> Do you mean a Python list? ''.join(mylist)
>
>No I mean a list of character values, like (97,98,99) => "abc".
>
You mean like this?

 >>> ''.join(map(chr,(97,98,99)))
 'abc'

>> > somebody seems to have faced that problem before and it's been taken
>> > care of in some reasonably thought-out way.  In Python, I often feel
>> > like I'm doing something that hasn't been done much before.
>> 
>> In part I suspect that's due to your inexperience with the language, but
>> please keep pointing out the things that are missing. :)
>
>Here's one: say I have a long int, like x = 7**77777L.  How can I tell
>how many bits it takes to express that number in binary?  How can I
>convert it into a packed character string (i.e. represent it in string
>form with 8 bits/char so I can write it to a file)?  The answers I can
>think of involve weird kludges and/or are unacceptably slow.
>
>Thanks.
Brute force, but easy to understand:
 >>> x = 7**77777L
 >>> cl = []
 >>> while x:
 ...     cl += chr(x&0xff)
 ...     x = x>>8
 ...
 >>> s = ''.join(cl)

Which gives you a little-endian result.

To get the string length required quickly, we can use
the builtin hex conversion which is very fast.
Note the '0x' in front and 'L' at the end (3 extra)
 >>> hex(x)[:5]
 '0xC7F'
 >>> hex(x)[-5:]
 'B487L'
 >>> len(hex(x))-3
 54587
 >>> (len(hex(x))-3+1)/2
 27294

That ought to hold the string, and is confirmed by
 >>> len(s)
 27294

That's not the exact number of bits, so define a function like so:
 >>> import math
 >>> def bitsin(x):
 ...     return math.frexp(eval(hex(x)[:3]))[1]+4*(len(hex(x))-4)
 ...
 >>> bitsin(7**77777L)
 218348

(It checks the bits in the first character and adds 4 each for the rest).

Since the first character is 'C' that's 4 bits, so all the hex chars
are 4 bits, for
 >>> len(hex(x))-3
 54587
 >>> (len(hex(x))-3)*4
 218348

which checks.
 >>> bitsin(7L)
 3
also checks (it assumes long type though, subtracting 1 for the 'L')


I grant you, the while loop takes a few seconds, and so does the 7**77777L.
How fast do you need? We could write faster algorithms for the exponentiations,
and also the conversion to string, both in Python. We could also obviously
write a fast extension to do it in C/C++ and return a string of 8-bit chars
as fast as the hex() function.
How fast do you need?





More information about the Python-list mailing list