10

In C# I could easily write the following:

string stringValue = string.IsNullOrEmpty( otherString ) ? defaultString : otherString;

Is there a quick way of doing the same thing in Python or am I stuck with an 'if' statement?

Jon Seigel
  • 11,819
  • 8
  • 53
  • 90
Jordan Parmer
  • 32,842
  • 27
  • 93
  • 118

9 Answers9

24

In Python 2.5, there is

A if C else B

which behaves a lot like ?: in C. However, it's frowned upon for two reasons: readability, and the fact that there's usually a simpler way to approach the problem. For instance, in your case:

stringValue = otherString or defaultString
Thomas Wouters
  • 118,131
  • 21
  • 139
  • 118
  • The second example /works/, but see my comment for how you can specify the comparison. – Serafina Brocious Sep 25 '08 at 19:09
  • 2
    Isn't that backwards? In general the and/or trick is frowned on because of gotchas like "cond and A or B", where A happens to be a false value like 0. There are workarounds like (cond and [A] or [B])[0], but the if/else syntax was added pretty much to remove the need for such abuse. – Brian Sep 25 '08 at 19:34
  • 1
    It's not backwards. The if/else syntax was added to 'fix' the need people had for a ternary operator that lead them to the broken and/or trick. However, notice how my example doesn't use 'and'. It just uses 'or', which is a much more straightforward way to do what the OP wanted. No gotcha's there. – Thomas Wouters Sep 25 '08 at 19:40
5

@Dan

if otherString:
   stringValue = otherString
else:
   stringValue = defaultString

This type of code is longer and more expressive, but also more readable

Well yes, it's longer. Not so sure about “more expressive” and “more readable”. At the very least, your claim is disputable. I would even go as far as saying it's downright wrong, for two reasons.

First, your code emphasizes the decision-making (rather extremely). Onthe other hand, the conditional operator emphasizes something else, namely the value (resp. the assignment of said value). And this is exactly what the writer of this code wants. The decision-making is really rather a by-product of the code. The important part here is the assignment operation. Your code hides this assignment in a lot of syntactic noise: the branching.

Your code is less expressive because it shifts the emphasis from the important part.

Even then your code would probably trump some obscure ASCII art like ?:. An inline-if would be preferable. Personally, I don't like the variant introduced with Python 2.5 because it's backwards. I would prefer something that reads in the same flow (direction) as the C ternary operator but uses words instead of ASCII characters:

C = if cond then A else B

This wins hands down.

C and C# unfortunately don't have such an expressive statement. But (and this is the second argument), the ternary conditional operator of C languages is so long established that it has become an idiom in itself. The ternary operator is as much part of the language as the “conventional” if statement. Because it's an idiom, anybody who knows the language immediately reads this code right. Furthermore, it's an extremely short, concise way of expressing these semantics. In fact, it's the shortest imaginable way. It's extremely expressive because it doesn't obscure the essence with needless noise.

Finally, Jeff Atwood has written the perfect conclusion to this: The best code is no code at all.

Konrad Rudolph
  • 482,603
  • 120
  • 884
  • 1,141
  • Correct me if you think I'm wrong, but this should be a comment to Dan's post rather than a new answer. You're right about his answer being debatable/disputable, but I'd say you've gone to far by saying "down right wrong." That's just mean... (Most physicists stand on each others' shoulders while most computer scientists stand on each others' toes.) – Pretzel Feb 08 '16 at 16:10
  • btw, I see why you felt a need to answer it as an answer, rather than a comment... (Stackoverflow wouldn't let my edit my comment...) – Pretzel Feb 08 '16 at 16:22
1

It's never a bad thing to write readable, expressive code.

if otherString:
   stringValue = otherString
else:
   stringValue = defaultString

This type of code is longer and more expressive, but also more readable and less likely to get tripped over or mis-edited down the road. Don't be afraid to write expressively - readable code should be a goal, not a byproduct.

Dan Udey
  • 2,895
  • 2
  • 19
  • 18
1

There are a few duplicates of this question, e.g.

In essence, in a general setting pre-2.5 code should use this:

 (condExp and [thenExp] or [elseExp])[0]

(given condExp, thenExp and elseExp are arbitrary expressions), as it avoids wrong results if thenExp evaluates to boolean False, while maintaining short-circuit evaluation.

Community
  • 1
  • 1
ThomasH
  • 19,270
  • 9
  • 53
  • 57
0

By the way, j0rd4n, you don't (please don't!) write code like this in C#. Apart from the fact that the IsDefaultOrNull is actually called IsNullOrEmpty, this is pure code bloat. C# offers the coalesce operator for situations like these:

string stringValue = otherString ?? defaultString;

It's true that this only works if otherString is null (rather than empty) but if this can be ensured beforehand (and often it can) it makes the code much more readable.

Konrad Rudolph
  • 482,603
  • 120
  • 884
  • 1,141
  • This is a good point (as I just learned about the coalesce operator a couple of weeks ago, but what about the case where empty strings are returned from a database query? Much of the code I write utilizes our company's database API which returns empty strings a lot. – Jordan Parmer Sep 25 '08 at 20:25
  • Referring to my ruby example, I wrote an IsBlank extension method in C# which does that. Dunno what you'd do in python – Orion Edwards Sep 25 '08 at 20:38
0

I also discovered that just using the "or" operator does pretty well. For instance:

finalString = get_override() or defaultString

If get_override() returns "" or None, it will always use defaultString.

Jordan Parmer
  • 32,842
  • 27
  • 93
  • 118
0

Chapter 4 of diveintopython.net has the answer. It's called the and-or trick in Python.

Dominic Rodger
  • 90,548
  • 30
  • 192
  • 207
Joo Park
  • 2,955
  • 4
  • 24
  • 31
-1

You can take advantage of the fact that logical expressions return their value, and not just true or false status. For example, you can always use:

result = question and firstanswer or secondanswer

With the caveat that it doesn't work like the ternary operator if firstanswer is false. This is because question is evaluated first, assuming it's true firstanswer is returned unless firstanswer is false, so this usage fails to act like the ternary operator. If you know the values, however, there is usually no problem. An example would be:

result = choice == 7 and "Seven" or "Another Choice"
Douglas Mayle
  • 18,173
  • 7
  • 40
  • 57
-1

If you used ruby, you could write

stringValue = otherString.blank? ? defaultString : otherString;

the built in blank? method means null or empty.
Come over to the dark side...

Orion Edwards
  • 113,829
  • 60
  • 223
  • 307