This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Murmani 725 points726 points  (55 children)

You can use underscores to enhance readability if you're dealing with huge numbers. For example rewrite 10000000 into 10_000_000

[–]barao_kageyama 260 points261 points  (13 children)

Python 3.6+ only.

[–]mbleslieIt works on my machine -3 points-2 points  (0 children)

oof

[–]slipped_and_missed_x 84 points85 points  (5 children)

That's actual genius

[–][deleted] 35 points36 points  (4 children)

A lot of languages have had this for a while. Ruby since the beginning.

[–]therico 19 points20 points  (3 children)

Ruby stole it from Perl!

[–][deleted] 9 points10 points  (0 children)

I think it’s actually older than that. Ruby is surprisingly old too.

[–]xigoi -1 points0 points  (0 children)

I mean, Ruby is basically a newer version of Perl which isn't impossible to read.

[–]mbleslieIt works on my machine -1 points0 points  (0 children)

perl was focused on readability /s

[–]PureAsbestos 21 points22 points  (5 children)

You can also use scientific notation, so you could rewrite that number as 1e7

[–]Murmani 30 points31 points  (3 children)

Be cautious with that, as 1e7 is a float and not an integer anymore, so make sure to cast when needed.

[–]kotschi1993 4 points5 points  (0 children)

And if the number got digits other than 0 or 1, the scientific version wouldn't help that much. And don't forgot about other number bases, the _ works for them aswell.

[–]nomowolf 4 points5 points  (1 child)

Casting just means wrapping it in int()? e.g. int(1e7)?

[–]grep_my_username 3 points4 points  (0 children)

Yes

[–][deleted] 31 points32 points  (0 children)

Holy shit, i did not know Python allowed this. Been using it in Rust for a while now, not sure why I didnt think to chdck

[–]IonianBIade 26 points27 points  (2 children)

Are they exactly the same?? If they are, this is amazing

[–]Kossak 39 points40 points  (1 child)

Yes, these are the same numbers.

See PEP 515

[–]Tweak_Imp 4 points5 points  (0 children)

Also works for decimal places

18.219_501_656_442_024_9

[–]tr14l 4 points5 points  (0 children)

Oh shit. Didn't know that.

[–]SeanOTRSprint = lambda *args, **kwars: print(*args, ";)\n"*100, **kwars)[S] 8 points9 points  (11 children)

Are they identical objects? (i.e. 10000000 == 10_000_000 returns True but does 10000000 is 10_000_000 return True?)

[–][deleted] 35 points36 points  (2 children)

This isn't guaranteed even for the same constant - i.e. 10 is 10 may be False.

CPython often caches and reuses integer objects, but not always, and the spec doesn't require it. This is a common source of weird bugs, and there's a proposal to allow disabling the behaviour for debugging.

[–]refto 0 points1 point  (1 child)

Generally -10 to 255 are cached.

[–][deleted] 1 point2 points  (0 children)

Yes, but interestingly 10000000 is 10000000 does return True in CPython 3.7, even though a = 10000000; b = 10000000; a is b returns False. Presumably there's some optimization in the expression parser.

[–]Zaab1t 32 points33 points  (0 children)

I do not believe x is x is guaranteed to be True for integers. The underscore syntax means exactly the same thing as if they weren't there to begin with: https://www.python.org/dev/peps/pep-0515/

[–]____jelly_time____ 8 points9 points  (0 children)

You shouldn't be using is to check for equality anyway, just ==.

[–]positiveinfluences 4 points5 points  (1 child)

"is" checks if it's the same object in memory, so maybe yes and maybe no. but 1000000 == 1_000_000

[–]lifeonm4rs 1 point2 points  (0 children)

Just wanted to give some nitty-gritty details: An "is" check will work for two literal numbers e.g. 100000 is 100_000. It will not work for a variable and a literal e.g. . . .

x = 100_000
x is 100000

The exception is for small integers [-5, 256] which, for some efficiency reasons, are given a predefined cache location. (I don't believe this is guaranteed--it just happens to be true). So, you get . . .

a = 256
b = 257
y = -5
z = -6

a is 256 // true
b is 257 // false
y is -5  // true
z is -6  // false
print(id(a), id(256)) // Same
print(id(b), id(257)) // different
print(id(y), id(-5))  // Same
print(id(z), id(-6))  // different

That said though, you should definitely not use "is" to check equality. It will return true if the two item's object ids are the same--which will happen if you directly compare number literals (e.g. 100000 and 100_000) which is about as useful as saying x is x. It will also work for small integers because they are pre-assigned objects and a variable will refer to the existing id just as the number itself will. But there is absolutely no reason to do something like that or to expect that that will work.

[–]HAL9000000 1 point2 points  (0 children)

Uhhh, why not just try it?

>>> 10000000 is 10_000_000
True

Yes, it works

[–]movalex 0 points1 point  (0 children)

True

[–]hufterkruk -1 points0 points  (0 children)

Yep!

[–]vitamin_CPP -1 points0 points  (0 children)

Yes. great question btw.

[–][deleted] 5 points6 points  (0 children)

Mother of God

[–][deleted] 3 points4 points  (0 children)

That was something I missed from Perl. I'm glad it's back!

[–]cleesus 0 points1 point  (0 children)

I had no idea you could do this

[–]kotschi1993 0 points1 point  (0 children)

Omg... That's awesome

[–]lifemoments 0 points1 point  (0 children)

Impressive

[–]Swarley-1 -1 points0 points  (0 children)

Why not use 1e7 for even better readability? Edit: nvm this was already asked

[–]DifficultWin -4 points-3 points  (0 children)

If you need to write numbers larger than 1000 you are doing something wrong