Is it okay to use itinerary operators in python without assignment?

Viewed 115

So, consider the case that I have to add values to an array based upon conditions. I realized using ternary operators without assignment works as well. Consider the case:

req_array = []
req_dict={'a':1,'b':2,'c':3}

I have to add values to req_array based upon condition. There can be 2 ways:

if req_dict.get("a"):
    req_array.append(req_dict['a'])
if req_dict.get("d"):
    req_array.append(req_dict['d'])
if req_dict.get("c"):
    req_array.append(req_dict['c'])

The other way of doing this is:

req_array.append(req_dict['a']) if req_dict.get('a') else None
req_array.append(req_dict['d']) if req_dict.get('d') else None
req_array.append(req_dict['c']) if req_dict.get('c') else None

Both of them works correctly. But, I was curious as to what is the recommended approach in these cases?

3 Answers

I'd view using the conditional operator for side-effects with roughly the same disgust as using list comprehensions for side-effects. These are expressions intended to produce something, and you're using them to do other things while ignoring the thing produced (always None in this case).

If you really need to one-line it, you can always do

if req_dict.get('a'): req_array.append(req_dict['a'])

which, while still not great style (two lines are more readable), is perfectly legal, less verbose (add :, remove else None), and doesn't imply the production of an unused value even when the if fails. With 3.8, the walrus operator even saves you from performing lookup twice, while still allowing you to one-line it:

if val := req_dict.get('a'): req_array.append(val)

As you noted, both options work, so it's a matter of personal style, mostly.

Personally, I find such ternary expression harder to read - they start with stating something will be appended to a list, but as you read on you find out it may not due to some condition. I would definitely got with the explicit if approach.

There are many ways to achieve this depending on what exactly you are looking for. Is condition always the same? Then you could define a list of keys and iterate over it.

keys = ['a', 'b', 'c']
req_array = []
req_dict={'a':1,'b':2,'c':3}
for key in keys:
    val = req_dict.get(key)
    if val:  # your condition here
        req_array.append(val)

Or one liner:

req_array += [req_dict[key] for key in keys if req_dict.get(key)]

There are many appropriate ways. Some are just a matter of preference.

If conditions are different for all of the keys, then i would go for explicit if as this is kind of more readable and the patter is vissually immediately recognizable.

Related