Dumb python questions

Paul Winkler slinkp23 at yahoo.com
Sat Aug 18 21:14:17 EDT 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".

Use the chr() built-in function to convert each list item to
ascii. For this, it's handy to use either a list comprehension (new
for python 2.x), or the map() function. Either way, you can then join
the result into a string. One example:

>>> ilist = range(65, 70)
>>> alist = [chr(x) for x in ilist]
>>> # OR: alist = map(chr, ilist)
>>> alist
['A', 'B', 'C', 'D', 'E']
>>> ''.join(alist)
'ABCDE'

>> > 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?

I think most people deal with binary data in python as strings.
 fastest thing I can think of is to use oct() or hex() to convert your
number to a string representation, then compute from the length of
that.
 
For example, if you can work with a count of nibbles rather than
bits, this will work:

def nibbles_needed(x):
    h = hex(long(x))
    return len(h) - 3  # compensate for leading '0x' and trailing 'L'

>From this you can do bytes:

def bytes_needed(x):
    n = nibbles_needed(x)
    bytes, remainder = divmod(n, 2)
    if remainder: return bytes + remainder
    else: return bytes


A test run:

>>> bytes_needed(100)
1
>>> bytes_needed(255)
1
>>> bytes_needed(256)
2
>>> bytes_needed(7**77777L)
27294


>  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.

Hmmm... my first thought was struct.pack but you'd first need to chop
the long up into (literally) byte-size pieces. And even when you've
done that, struct.pack() won't take a list as an argument.

Aside from struct, there's the binascii module which you might find
useful. For example, here's a pretty fast way to do what you asked
for:

>>> from binascii import a2b_hex
>>> def charlist(x):
...    x = long(x)
...    # Now create a hex representation,
...    # but without the leading 'Ox' or trailing 'L'.
...    h = hex(x)[2:-1] 
...    # Split that up into actual bytes.
...    bytes = [h[i:i+2] for i in range(0,len(h),2)]
...    chars = [a2b_hex(b) for b in bytes]
...    return chars
...
>>> charlist(97)
['a']
>>> charlist((97 * 2 ** 8) + 98)
['a', 'b']
>>> x = charlist(7**77777L)
>>> len(x)
27294


Hope that helps!








More information about the Python-list mailing list