5

I ran across some python code syntax that I have never seen before. Here is an example:

i = 0
for spam in range(10):
    i += [1, 3][i > 5]
    print(i)

The result is the sequence of 1,2,3,4,5,6,9,12,15,18. So, it increments by 1 until i > 5, then increments by 3 thereafter.

Previously, I would have written the line as:

if i > 5:
    i += 3
else:
    i += 1

So what is the line: i += [1, 3][i > 5]?

  • What do you call that syntax structure?
  • Is it some form of list comprehension or something else entirely?

The syntax is interesting and I wanted to read more about it, but don't know where to look.

Edit: Thank you Darkstarone. I had never thought of using an expression to return a list index. That is very cool. This means you could also do things like: spam = ["Even", "Odd"][eggs % 2] to return an even or odd string or foo = ["A", "B", "C"][zot % 3] to cycle through three choices when looping through values of zot.

Probably won't make a habit of using this construct since other expressions are easier to understand. But, I'll take this into the bag o' tricks for that perfect situation.

5
  • 2
    It doesn't have a special name, they're just indexing into a list: True == 1 and False == 0. It's not a list comprehension, that would have for and in. It's also not a great way to write it due to exactly your current confusion, vs. a more straightforward ternary expression. Commented May 18, 2017 at 22:41
  • It's "that ternary kludge with the list indexing", as distinct from "that ternary kludge with and/or" (i > 5 and 3 or 1) and "the actual conditional expression syntax" (3 if i > 5 else 1). Commented May 18, 2017 at 22:43
  • This is pretty cool syntactic sugar. It's pretty obscure on first viewing but after realizing it's ternary in nature it actually becomes very clear though, extending it may obfuscate it since it's list-indexing, essentially... I guess you could just nest things. It can be a bit hairy... [[1,3][k > 4], [4,5][k>6]][k > 6] Commented May 19, 2017 at 13:54
  • I wouldn't call it syntactic sugar; the indexing is just applied to a list literal rather than a named list object, and for better or worse, a Boolean value is an integer in Python. Commented May 19, 2017 at 13:59
  • Yeah, I guess you're right in that it's not syntactic sugar. It's a pretty cool twist on what we may consider a traditional ternary method. I wonder if there's modest performance boost or something that justifies using this method. Commented May 19, 2017 at 15:59

2 Answers 2

4

So what I believe is happening here is the list ([1,3]) can either be:

[1,3][0] # 1

Or

[1,3][1] # 3

It's taking advantage of the fact that 0 == False and 1 == True. It's rather neat, although a little opaque. I probably would have written it like so:

i = 0
for _ in range(10):
    i += 3 if i > 5 else 1
    print(i)
Sign up to request clarification or add additional context in comments.

Comments

0

Ternary operator, is written like this:

i += 3 if i > 5 else 1

1 Comment

This doesn't answer the OP's question, though. What they're looking at isn't a ternary expression (not operator).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.