58

Is it considered bad style to assign values to variables like this?

x = "foobar" or None
y = some_variable or None

In the above example, x gets the value 'foobar'.

TheOne
  • 10,819
  • 20
  • 81
  • 119
  • 1
    I don't see any function being called just truth testing. Where are the side effects? – jcollado Jan 05 '12 at 18:31
  • 4
    That's not what a "side effect" is. – Greg Hewgill Jan 05 '12 at 18:42
  • @jcollado: I am not assigning a boolean to x and y. The value that gets assigned is the first short-circuited item that is True. The first case being "foobar", and the latter depends on the boolean value of some_variable. – TheOne Jan 05 '12 at 19:23
  • 3
    @Ramin I know you're not assigning a boolean. My point is that I don't see any [side effect](http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29). – jcollado Jan 05 '12 at 19:28
  • @jcollado, what would you call the behavior of the `or` operator where a boolean result is expected, but conveniently the first true value is returned? – TheOne Jan 05 '12 at 19:38
  • 4
    @Ramin: "A somewhat unusual behavior", "side effect" has a very different meaning in computer science. http://en.wikipedia.org/wiki/Side_effect_(computer_science) – joaquin Jan 05 '12 at 19:47
  • C++ be damned for all the confusion! Or was C the first language to use the ++ operator? Does python even have side-effects? – TheOne Jan 05 '12 at 19:56
  • 4
    Yes Python has them, terrible, dark, dangerous (a Haskeller) – joaquin Jan 05 '12 at 20:19
  • 2
    Related: [What does an 'x = y or z' assignment do in Python?](https://stackoverflow.com/q/21566106/3357935) – Stevoisiak May 04 '18 at 13:55

4 Answers4

43

No, it's a common practice. It's only considered bad style for expressions that are considerably longer than yours.

tback
  • 11,138
  • 7
  • 47
  • 71
  • 2
    It is considered an anti-pattern in JavaScript. It does not read naturally to uninitiated and you cannot assign falsy values. – diginoise Sep 21 '17 at 08:21
  • 12
    @diginoise Nothing in Javascript or any other language reads naturally to the sufficiently uninitiated. But once a developer is familiar with short-cut evaluation (as used in, e.g., `if foo or bar...`, which is quite a common idiom in JS, Python and many other languages) it reads just as naturally, though you may have to think about it for a moment the very first time you see it. However, "falsy" values are a problem in Python, too, as with 'list = []; return list or False` – cjs Jun 08 '18 at 05:18
32

The primary danger of doing something like this is the possibility that (in the second case) some_variable is False but not None (the integer 0, for instance) and you don't want to end up with y equal to None in that case.

Free Monica Cellio
  • 2,270
  • 1
  • 16
  • 15
9

OP's syntax is perfectly fine.
The official name for "assignment with or" is null coalescing and there's actually a Wikipedia page about it now! https://en.wikipedia.org/wiki/Null_coalescing_operator
This question may be useful as well: Is there a Python equivalent of the C# null-coalescing operator?

DonCarleone
  • 544
  • 11
  • 20
9

I also feel a bit unconfortable using that kind of expressions. In Learning Python 4ed it is called a "somewhat unusual behavior". Later Mark Lutz says:

...it turns out to be a fairly common coding paradigm in Python: to select a nonempty object from among a fixed-size set, simply string them together in an or expression. In simpler form, this is also commonly used to designate a default...

In fact, they produce concise one-line expressions that help to eliminate line noise from the code.
This behavior is the basis for a form of the if/else ternary operator:

A = Y if X else Z
joaquin
  • 82,968
  • 29
  • 138
  • 152
  • 4
    But it may cause to repeat a long parameters where `Y = X`. For instance: `A = my_main_dictionary.my_sub_dictionary.my_value if my_main_dictionary.my_sub_dictionary.my_value else None` or `A = my_main_dictionary.my_sub_dictionary.my_value or None` – Roee Gavirel Sep 18 '17 at 07:19
  • 2
    @RoeeGavirel just assign `my_value` to a local variable – winklerrr Jul 17 '19 at 07:29