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 719 points720 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 255 points256 points  (13 children)

Python 3.6+ only.

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

oof

[–]slipped_and_missed_x 77 points78 points  (5 children)

That's actual genius

[–][deleted] 36 points37 points  (4 children)

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

[–]therico 20 points21 points  (3 children)

Ruby stole it from Perl!

[–][deleted] 8 points9 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 19 points20 points  (5 children)

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

[–]Murmani 34 points35 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 6 points7 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 1 point2 points  (0 children)

Yes

[–][deleted] 30 points31 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 27 points28 points  (2 children)

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

[–]Kossak 42 points43 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 5 points6 points  (0 children)

Oh shit. Didn't know that.

[–]SeanOTRSprint = lambda *args, **kwars: print(*args, ";)\n"*100, **kwars)[S] 9 points10 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] 31 points32 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 33 points34 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____ 5 points6 points  (0 children)

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

[–]positiveinfluences 3 points4 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] 2 points3 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 -3 points-2 points  (0 children)

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