4

I have a list that will sometimes hold a single value, sometimes 2 or 3 values. I am assigning each of the values to a variable. If there is no value for the assigned position of the list, I want it to be a empty variable. Is there any way I can make this more efficient?

split = line.split(',')
try:
    var1 = split[0]
except IndexError:
    var1 = None
    
try:
    var2 = split[1]
except IndexError:
    var2 = None

try:
    var3 = split[2]
except IndexError:
    var3 = None
wjandrea
  • 28,235
  • 9
  • 60
  • 81
pcct2019
  • 41
  • 2
  • sounds like a usage of `dict`. can't you use `dict` to store these values instead of storing these in separate variables? – Moinuddin Quadri Jan 19 '21 at 19:17
  • 1
    Related: [How do I create variable variables?](https://stackoverflow.com/q/1373164/4518341) – wjandrea Jan 19 '21 at 19:19
  • 1
    Does this answer your question? [Multiple try codes in one block](https://stackoverflow.com/questions/17322208/multiple-try-codes-in-one-block) – Always Greg Jan 19 '21 at 19:24
  • 1
    `var1, var2, var3 = (split + [None] * 3)[:3]`. – ekhumoro Jan 19 '21 at 19:30
  • If `line` is a string, `split[0]` will always exist. So is there a reason you're expecting an `IndexError`? For example, `''.split(',')` -> `['']` – wjandrea Jan 19 '21 at 21:06

3 Answers3

1
split = line.split(',')
variables = [None, None, None]


for i in range(len(split)):
        variables[i] = split[i]

var1, var2, var3 = variables

Edit (after @ekhumoro):

split = line.split(',')
variables = [None, None, None]
variables[:len(split)] = split
var1, var2, var3 = variables
godot
  • 3,422
  • 6
  • 25
  • 42
  • 2
    `vars[:len(split)] = split`. – ekhumoro Jan 19 '21 at 19:43
  • [`vars()`](https://docs.python.org/3/library/functions.html#vars) is a builtin, so it'd be better to use a different name, to avoid shadowing. C.f. this problem: [TypeError: 'list' object is not callable in python](https://stackoverflow.com/q/31087111/4518341) – wjandrea Jan 19 '21 at 22:50
0

You can use generator expression (or list comprehension) with conditional check to see if the index exists in the list. If exists, return element at that index, else return None. Here I am limiting my generator expression to return n (which is 3 in your case) values, and you can unpack and save these values in n variables.

For example:

my_list = [1] # List with just one element
n = 3  # Number of variables in which you want to fill the values

var1, var2, var3 = (my_list[i] if i < len(my_list) else None for i in range(n))

print(var1, var2, var3)
# prints: (1, None, None)

Refer Generator Expressions and List Comprehensions for more details.

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • @pcct2019 Did this answer and other answers here helped you? If yes, please upvote the answers by hitting the "up" arrow on the left of the answers. You can also mark the best answer as accepted by hitting "tick" icon. It helps answerer with reputation gain of +10 for each upvote and +15 for accepted answer. – Moinuddin Quadri Feb 07 '21 at 16:21
0

Depending on what you're actually trying to accomplish*, it might be better to not use individual variables. For example, you could use dict.get(), which returns None if the given key is not in the dict.

for line in 'a,b,c', 'd,e', 'f':
    split = line.split(',')
    d = {i: v for i, v in enumerate(split)}
    print(d, ' -> ', d.get(0), d.get(1), d.get(2))

Output:

{0: 'a', 1: 'b', 2: 'c'}  ->  a b c
{0: 'd', 1: 'e'}  ->  d e None
{0: 'f'}  ->  f None None

You could also consider using unpacking:

for line in 'a,b,c', 'd,e', 'f':
    var1, *others = line.split(',')
    print(var1, others)

Output:

a ['b', 'c']
d ['e']
f []

By the way, note that split[0] will always exist, so I'm not sure why you're expecting an IndexError. For example:

>>> ''.split(',')
['']

* See some related ideas at How do I create variable variables? and more broadly, how to avoid the XY problem

wjandrea
  • 28,235
  • 9
  • 60
  • 81