views:

670

answers:

6

In python, is there a command similar to len() which works on integers?

Thanks

+5  A: 

If you want the length of an integer as in the number of digits in the integer you can always typecast it to string like str(133) and find its len like len(str(123)).

GeekTantra
Of course, if you're looking for the number of digits, this will produce a result that's too large for negative numbers, since it will count the negative sign.
Chris Upchurch
Thank you for the quick response
Strigoides
This is conversion, not casting. Python doesn't have any casting.
Aaron Gallagher
`len(str(abs(v)))` if you are worried about the negative sign ...
wisty
Conversion in python analogous to typecasting in other languages. As wisty said. for negative numbers you always have absolute values.
GeekTantra
A: 

Assuming you are asking for the largest number you can store in an integer, the value is implementation dependent. I suggest that you don't think in that way when using python. In any case, quite a large value can be stored in a python 'integer'. Remember, Python uses duck typing!

Edit: I gave my answer before the clarification that the asker wanted the number of digits. For that, I agree with the method suggested by the accepted answer. Nothing more to add!

batbrat
+7  A: 

Without conversion to string

import math
digits = int(math.log10(n))+1

To also handle zero and negative numbers

import math
if n > 0:
    digits = int(math.log10(n))+1
elif n == 0:
    digits = 1
else:
    digits = int(math.log10(-n))+2 # +1 if you don't count the '-' 

You'd probably want to put that in a function :)

Here are some benchmarks. The len(str()) is already behind for even quite small numbers

timeit math.log10(2**8)
1000000 loops, best of 3: 746 ns per loop
timeit len(str(2**8))
1000000 loops, best of 3: 1.1 µs per loop

timeit math.log10(2**100)
1000000 loops, best of 3: 775 ns per loop
 timeit len(str(2**100))
100000 loops, best of 3: 3.2 µs per loop

timeit math.log10(2**10000)
1000000 loops, best of 3: 844 ns per loop
timeit len(str(2**10000))
100 loops, best of 3: 10.3 ms per loop
gnibbler
Broken for 0, but good solution.
Paul Hankin
Also broken for negative numbers.
Wallacoloo
Perhaps `digits = n and 1 + int(math.log(abs(n), 10))`
Paul Hankin
Using log10 for this is a mathematician's solution; using len(str()) is a programmer's solution, and is clearer and simpler.
Glenn Maynard
@Glenn: I certainly hope you aren't implying this is a bad solution. The programmer's naive O(log10 n) solution works well in ad-hoc, prototyping code -- but I'd much rather see mathematicians elegant O(1) solution in production code or a public API. +1 for gnibbler.
Juliet
It's not elegant at all; it's six lines of code and much less understandable, and smells badly of premature optimization.
Glenn Maynard
@Glenn: It's quite understandable to me, and it was the first approach I had in mind (and one I've implemented a number of times). If it's not understandable in general, perhaps a comment or two would be good. Preferring what looks short and elegant on the surface (but has hidden factors of complexity) is good for codegolf but not always good in general.
KirarinSnow
It's better to be correct than to be wrong and fast. len(str(abs(x))) has the advantage that it's pretty bloody hard to get wrong. Heck, even len(str(x)) is only wrong to some people ;).
Devin Jeanpierre
+4  A: 

Python 2.* ints take either 4 or 8 bytes (32 or 64 bits), depending on your Python build. sys.maxint (2**31-1 for 32-bit ints, 2**63-1 for 64-bit ints) will tell you which of the two possibilities obtains.

In Python 3, ints (like longs in Python 2) can take arbitrary sizes up to the amount of available memory; sys.getsizeof gives you a good indication for any given value, although it does also count some fixed overhead:

>>> import sys
>>> sys.getsizeof(0)
12
>>> sys.getsizeof(2**99)
28

If, as other answers suggests, you're thinking about some string representation of the integer value, then just take the len of that representation, be it in base 10 or otherwise!

Alex Martelli
Sorry this answer got minus-ed. It is informative and to the plausible point of the question (if it were only more specific about which 'len' is desired). +1
mjv
A: 
>>> a=12345
>>> a.__str__().__len__()
5
ghostdog74
Do not directly call special methods. That is written `len(str(a))`.
Mike Graham
yes i know. what's the big problem? if its there, i can use it.
ghostdog74
@ghostdog74 Just because there's an electrical socket, doesn't mean you have to stick your fingers in it.
Paul Hankin
so if you are so against it, why don't you tell me what's wrong with using it?
ghostdog74
"Magic" __ methods are there for Python internals to call back into, not for your code to call directly. It's the Hollywood Framework pattern: don't call us, we'll call you. But the intent of this framework is that these are magic methods for the standard Python built-ins to make use of, so that your class can customize the behavior of the built-in. If it is a method for your code to call directly, give the method a non-"__" name. This clearly separates those methods that are intended for programmer consumption, vs. those that are provided for callback from Python built-ins.
Paul McGuire
still, you don't say why its especially bad to use special methods.
ghostdog74
It'sa bad idea because *everyone else in the known universe* uses str() and len(). This is being different for the sake of being different, which is inherently a bad thing--not to mention it's just ugly as hell. -1.
Glenn Maynard
that's so twisted. Just because majority of u uses str,len does not mean i have to follow. these methods are exposed to the programmer when the int object is instantiated, and i can jolly well use as i please. did GVR specifically sat we cannot use them?
ghostdog74
+1  A: 
from math import log10
digits = lambda n: ((n==0) and 1) or int(log10(abs(n)))+1
Robert William Hanks