Re: "number-in-base" ``oneliner''

From: Bengt Richter (bokr_at_oz.net)
Date: 10/30/04


Date: Sat, 30 Oct 2004 06:07:23 GMT

On Fri, 29 Oct 2004 23:58:47 +0200, aleaxit@yahoo.com (Alex Martelli) wrote:

>I hesitate a bit to post this, but... on the Italian Python NG, somebody
>was asking whether there was any way to convert an integer number x into
>a string which represents it in an arbitrary base N (given a sequence
>with a len of N that gives the digits to use) as "a single expression".
>
>I haven't found a really general way, much less a clear one, but, the
>best I have so far is...:
>
>def number_in_base(x, N, digits, maxlen=99):
> return '-'[x>=0:] + (
> (x and ''.join([digits[k%N] for i in range(maxlen)
> for k in [abs(x)//N**i] if k>0])[::-1]
> ) or digits[0])
>
>Besides the lack of clarity, the obvious defect of this approach is that
>darned 'maxlen' parameter -- but then, since I can have only a 'for',
>not a 'while', in a list comprehension or generator expression, and I
>don't think recursion qualifies as 'a single expression'...:-(
>
>Anyway, improvements and suggestions welcome, thanks!
>
Maybe something useful in this? Not very tested (and not terribly clear either ;-)

>>> def number_in_base(x, N, digits):
 ... return x==0 and digits[0] or '-'[:x<0] + ''.join([d for d in iter(
 ... lambda qr=[abs(x),0]:qr[0] and (
 ... qr.__setslice__(0,2,divmod(qr[0],N)) or digits[qr[1]])
 ... , 0)][::-1])
 ...
>>> number_in_base( 126 ,2,'0123456789ABCDEF')
 '1111110'
>>> number_in_base( 126 ,8,'0123456789ABCDEF')
 '176'
>>> number_in_base( 126 ,16,'0123456789ABCDEF')
 '7E'
>>> number_in_base( 1 ,16,'0123456789ABCDEF')
 '1'
>>> number_in_base( 0 ,16,'0123456789ABCDEF')
 '0'
>>> number_in_base(-126 ,16,'0123456789ABCDEF')
 '-7E'
>>> number_in_base(-126 ,2,'0123456789ABCDEF')
 '-1111110'

Even less tested, and using a list subtype with overridden next to do the same:

>>> def number_in_base(x, N, digits):
 ... return x==0 and digits[0] or '-'[:x<0] + ''.join([d for d in type('',(list,),{
 ... '__iter__':lambda s:s, 'next':lambda s:(
 ... s[0] is 0 and iter([]).next() or
 ... s.__setslice__(0,2,divmod(s[0],N)) or digits[s[1]])
 ... })([abs(x),0])][::-1])
 ...
>>> number_in_base(-126, 8, '01234567')
 '-176'
>>> number_in_base(-126, 2, '01')
 '-1111110'
>>> number_in_base(126, 2, '01')
 '1111110'
>>> number_in_base( 0 , 2, '01')
 '0'
>>> number_in_base( 1 , 2, '01')
 '1'

;-)

Regards,
Bengt Richter



Relevant Pages

  • Re: "number-in-base" ``oneliner
    ... >a string which represents it in an arbitrary base N (given a sequence ... >not a 'while', in a list comprehension or generator expression, and I ...
    (comp.lang.python)
  • Re: "number-in-base" ``oneliner
    ... >a string which represents it in an arbitrary base N (given a sequence ... >not a 'while', in a list comprehension or generator expression, and I ... will anything that works in a list comprehension work in a generator expression ...
    (comp.lang.python)
  • Re: number of different lines in a file
    ... Interesting that omitting them doesn't seem to matter. ... if you change the square brackets to ordinary parentheses, you get a generator expression instead: ... the generator expression results in an iterator object that calculates the values one by one. ... (in this case, you still need memory to hold the set, of course, so the difference between a list comprehension and a generator expression will only matter if you have lots of duplicates). ...
    (comp.lang.python)
  • Re: RELEASED Python 2.4, alpha 1
    ... bokr@oz.net (Bengt Richter) wrote in message ... > a semantic difference between (I don't have the generator expression version yet): ... Yes, I was unsure of the right term to use, I meant late lookup (so ... > The list comprehension didn't generate a different lookup: ...
    (comp.lang.python)
  • Re: number of different lines in a file
    ... the generator expression results in an iterator object that calculates the values one by one. ... (in this case, you still need memory to hold the set, of course, so the difference between a list comprehension and a generator expression will only matter if you have lots of duplicates). ... Basically, uniq died on this task (well, it probably was working, but ...
    (comp.lang.python)