What does [b, c][a < b < c]+'000'[a < c:] expression do?

Viewed 88

This is the code about to find out dice gamble's prize amount:

a, b, c = map(int, input().split())
if a == b and b == c:   #same all of dice numbers
    print(10000 + (a * 1000))
elif a == b or b == c:  #same two of dice numbers
    print(1000 + (b * 100))
elif a == c:            #same two of dice numbers
    print(1000 + (a * 100))
else:                   #no same number
    print(max(a, b, c)*100)

This is equivalent:

*_, a, b, c=sorted(input())
print(['1'+b, c][a < b < c]+'000'[a < c:])

But i can't understanding about what does ['1'+b, c][a < b < c] and '000'[a < c:] do.

So, I had tried to find out the meaning of

`['1'+b, c][a < b < c]`

I found this is similar with

`c if a<b<c else '1'+b`

but i can't be sure about that.

anyway, about

`'000'[a < c:]`

I tried input a=c to

`print('000'[a < c:])`

It shows 000.

I tried else that input a<c, it shows 00

Anyone can tell me about this expression?

3 Answers

The original is unnecessarily cryptic. It uses the fact that:

int(False) == 0
int(True)  == 1

For instance,

'000'[False:]  == '000'[0:] == '000'
'000'[True:]   == '000'[1:] == '00'

Similarly,

['1' + b, c][False] == ['1' + b, c][0] == '1' + b
['1' + b, c][True]  == ['1' + b, c][1] == c

Here's an equivalent rewrite:

prefix = c if a < b < c else '1' + b
suffix = '00' if a < c else '000'
print(prefix + suffix)

The string '000' has length 3. The boolean a < c has value False or True. The operation s[i] for a string s and integer i refers to the i'th element of s, and the operation s[i:] takes the substring of s from index i through the end of s. A boolean value will be converted to an integer in Python as follows: False becomes 0 and True becomes 1.

So, '000'[a < c:] is the same as '000'[0:] if a < c is False, and this is the same as '000'. If a < c is True, then '000'[a < c:] is the same as '000'[1:] which is '00'.

a < c will evaluate to either True or False. So you are effectively getting either print('000'[True:]) or print('000'[False:]).

When you have the [] after a string, those will perform a slice on the string. You'd see this in actually practice as something like the following (here's a link for more info:

'abcde'[2] # returns 'c', which, starting from zero, is 2nd item
'abcde'[0] # returns 'a', which is the zero-th item
'abcde'[1:3] # returns 'bc', starting from the 1st item and going to the 3rd, not inclusive of the third

It looks like if you use booleans in such a slice, the False acts as a 0 and True acts as a 1

"abcde"[True] == "abcde"[1] # evaluates to true, these are the same
'abcde'[True] # evaluates to 'b'
"abcde"[False] == "abcde"[2] # evaluates to `False`
"abcde"[True] == "abcde"[2] # evaluates to `False`
"abcde"[False] == "abcde"[0] # evaluates to True, because False is effectively 0 here

So, having a [True:] or [False:] in that string-slice is the same as having [1:] or '[0:]`, which is saying to "give all characters starting with the second (for True/1:) or first (for False/0:) in this string".

Related