2

In languages with optional types, you have a fn called orElse or getOrElse which lets you do this:

None.getOrElse(1) == 1
Some(2).getOrElse(1) == 2

I.e. you can specify a default value. In Python, I find I am writing:

if output_directory:
    path = output_directory
else:
    path = '.'

and it would be cleaner with a getOrElse call. Searching for orElse and getOrElse turns up logical operators. Is there a suitable Python fn?

Edit: getOrElse is not the same as a ternary operator call because that requires you to reference output_directory twice. Which is a particular issue if it's replaced with a complex expression. (Quite normal in a functional style.)

Mohan
  • 7,302
  • 5
  • 32
  • 55
  • The closest you can get is using a ternary: `path = output_directory if output_directory else '.'` – cs95 Mar 06 '18 at 13:05
  • Possible duplicate of [Does Python have a ternary conditional operator?](https://stackoverflow.com/questions/394809/does-python-have-a-ternary-conditional-operator) – Keyur Potdar Mar 06 '18 at 13:09

3 Answers3

7

Note that the above solution does not work precisely like the canonical getOrElse semantics of an FP language such as Scala or Haskell in corner cases where the bool(x) == False. For example

Some(0).getOrElse(1) == 0
Some('').getOrElse('A') == ''

but for either of the two definitions below

def getOrElse1(x, y):
  return x or y

def getOrElse2(x, y):
  return x if x else y

we have

getOrElse(x=0, 1) == 1
getOrElse(x='', 'A') == 'A'

An equivalent semantics is given by the definition:

def getOrElse(x, y):
  return x if x is not None else y
6

Just use or for equivalent logic:

path = output_directory or '.'
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
  • 1
    This is not correct. The or operator does not check for `None` but for `False` after conversion to `bool`. There is WIP: https://peps.python.org/pep-0505/ – Arne May 03 '23 at 11:39
  • @Arne Thank you for pointing that out! Please write an answer and I will delete this answer – Chris_Rands May 03 '23 at 19:32
  • Could you delete it anyway? Almost used it. I don't think he'll post an answer detailing what *doesn't* work – Juergen Jul 03 '23 at 17:20
  • Can’t delete an accepted answer- flagged for deletion instead – Chris_Rands Jul 07 '23 at 16:26
0

As commented above the or will not work as intended if the value of output_directory is falsy. For example output_directory = "" would cause the default to be chosen. Being fair, the original code block assumes that as well.

Using a Ternary at least puts things on one line.

path = output_directory if output_directory is not None else '.'

haagmm
  • 583
  • 6
  • 10