views:

365

answers:

4

I need to turn a formatted integer into a regular integer:

  • 000000000001 needs to be turned into 1
  • 000000000053 needs to be turned into 53
  • 000000965948 needs to be turned into 965948

And so on.

It seems that a simple int(000000000015) results in the number 13. I understand there is some weird stuff behind the scenes. What is the best way to do this accurately every time?

+11  A: 

Numbers starting with 0 are considered octal.

>>> 07
7
>>> 08
   File "<stdin>", line 1
   08
    ^
SyntaxError: invalid token

You can wrap your zero-padded number into a string, then it should work.

>>> int("08")
8

int() takes an optional argument, which is the base, so the above would be the equivalent of:

>>> int("08", 10)
8
The MYYN
to the downvoter ... something wrong?
The MYYN
I don't know why you're getting downvotes - this is absolutely right.
Lucas Jones
the answer was just ">>> int(08) \n 8" when I downvoted.
Kimvais
@Kimvais (or others): the answer has been edited in any case, and is the only really useful one here at the moment (since the missing base argument is *not* the issue), so you can remove your downvotes.
Peter Hansen
Removed the downvote.On a sidenote, the real issue here is still unresolved - where is OP getting **formatted** integer literals from - I think the formatted numbers should be *strings* not integer literals in any case
Kimvais
@Kimvais In one sense, it was up in the air whether they were strings or literals. I understand now that literals would be impossible unless I was reading them from a text file. They are coming from a database, so what I've decided to do is keep storing them as Integers without the trailing zeros, and just format them on output when needed with a method I created.
orokusaki
@orokusaki, *literals* by definition occur only text treated as Python source code, not just any "text file". If you read a text file in the usual manner (call `open()` etc) you are getting *strings*, not integer literals. And most of these answers tell you how to deal with this data as strings, though most incorrectly suggest you'd need the optional base 10 argument.
Peter Hansen
Peter: `help(int)`: "When converting a string, use the optional base."
Roger Pate
@Roger, but the online docs read "The base parameter gives the base for the conversion (which is 10 by default)", so you don't *need* the optional base as some of the answers have said.
Peter Hansen
@Peter: When the docs *explicitly* say something should be specified, I can't, with a straight face, recommend not specifying it. Pre-2.6 Python will do the wrong thing if you don't, in fact.
Roger Pate
@Roger, the `help()` docs are necessarily succinct, so I don't treat them as gospel. Furthermore, unless you're talking about something else, int("010") has never returned 8 instead of 10. I just tested in 2.5, and I'm pretty confident it's been that way since at least 1.5. Not sure why you're saying pre-2.6 requires it.
Peter Hansen
@Peter: I see your reply to Paul about pre-2.6 now. That the help() docs are succinct and it was still important enough to mention should say something. "Explicit is better than implicit", especially when the input looks like it might be written in another base.
Roger Pate
@Roger, it says to me that the writer probably didn't think enough about what he really wanted to say. ;-) Anyway, likely neither of us will sway the other's opinion on this matter, nor is it worth debating further.
Peter Hansen
A: 
if x = "0000000000000001":
    x = 1
Fragsworth
I'll just create 1 trillion versions of that.
orokusaki
orokusaki: Generate them: `for x in xrange(1000**4): print "if x == '%012d': x = %d" % (x, x)`
Roger Pate
I tried that, but the resulting file was 7.1 exabytes. Do you recommend putting it on S3 and running it through a socket, or should I get some ram disks?
orokusaki
I upvoted this seven times in an effort to counter the downvotes. Oh well.
BipedalShark
Much better to create a trillion-element dict: {"000000000000001" : 1, "000000000000002":2, etc.} - *much* more Pythonic
Paul McGuire
I really would love to never use something that has your code inside :)
kibitzer
@Paul, define it as a dict subclass with `def __getitem__(self, k): return int(k)` and no elements, and it will fit in well under 7.1 exabytes. ;-)
Peter Hansen
orokusaki: I can sell you a Python optimizer that compiles that exact generated code down to *one trillionth* its size! What other products can claim such efficiency?
Roger Pate
@Roger Pate Generator function? Simply not enough for me. I want all trillion in memory first, then into SSD SAN with redundancy.
orokusaki
+6  A: 

The leading zeroes are considered octal. I am assuming that you are converting the string "000000013", not literal 000000013, so you should be able to convert these to base 10 integer by int("000000013",10)

If the "harm has already been done", and they are literals, that have already been converted to octal literals, you can use the following (beware, this is harmful and heresy:)

int(("%o" % 00000013),10)
Kimvais
+1, but I've just tested this, and you don't need to specify the `10`.
Lucas Jones
@Lucas Jones, correct, but I think in this case it does less harm to explicitely state it as the int() function is only used to strip the leading zeroes.
Kimvais
lstrip, not rstrip.
FogleBird
This will fail if you pass it any number of "0"s without any other digits.
Ignacio Vazquez-Abrams
@Kimvais Thanks. So: Would it be wise to store this as an integer or a string?
orokusaki
@Kimvais: Fair point :).
Lucas Jones
I'd say as integer, and do the formatting only afterwards...
Kimvais
+3  A: 

Try this:

>>> int('00000000053', 10)
53
jbochi
The default base is 10 anyway.
Georg
@gs - not if there are leading 0's, then the assumed base is 8.
Paul McGuire
Paul: `int("010")` gives me 10, not 8; `int("01A")` gives "ValueError: invalid literal for int() with base 10". gs: However, `help(int)` still says "when converting a string, use the optional base", and we do tell people to read and follow the docs, right? :P
Roger Pate
@Roger: I think we may be talking about two different versions of Python. Pre 2.6 versions assume that leading 0 is an octal constant. I believe Py3 is doing away with that convention, and assuming base is 10 no matter what.
Paul McGuire
Yes, I'm using 2.6. Nice catch.
Roger Pate
@Paul, it's not correct that pre-2.6 versions assume that. For strings converted with `int()` the default base has always been 10, not 8 or 0 (when it "guesses", by treating the string the same way the compiler treats integer literals).
Peter Hansen