Using a list name as a string to access a list

I have a file with data that I want to split into different lists depending on the value in the first column. I know exactly what the possible values ​​are in the first column, but they are not in any good mathematical progression. Is there a shorter way to write the following code?

x0=[] y0=[] x2=[] y2=[] x16=[] y16=[] # etc. for line in file: words=line.split() if words[0] == '0': x0.append(words[1]) y0.append(words[2]) elif words[0] == '2': x2.append(words[1]) y2.append(words[2]) elif words[0] == '16': x16.append(words[1]) y16.append(words[2]) # etc. 

My thinking process is lower, but the strings (x and y) that I define are obviously strings and do not reference the lists that I want them to reference.

 x0=[] y0=[] x2=[] y2=[] x16=[] y16=[] # etc for line in file: words=line.split() x='x'+words[0] y='y'+words[0] x.append(words[1]) y.append(words[2]) 

Update: I understand that this can be done with a dictionary where my meaning will be a list of lists, but basically I'm curious if there is a pythonic way to code this, which follows my thought movement, as stated above.

+4
source share
5 answers

Use defaultdict instead of several separate values.

 from collections import defaultdict extracted_values = defaultdict(list) for line in file: words = line.split() extracted_values['x' + words[0]].append(words[1]) extracted_values['y' + words[0]].append(words[2]) 

Then you simply access your values ​​with a dictionary key instead of a variable name.

 extracted_values['x0'] extracted_values['y1'] 
+6
source

I suggest you turn on

 x0=[] x2=[] x16=[] 

in one dictionary:

 x={'0':[], '2':[], '16':[]} 

You can then reference individual lists as x['0'] , x['2'] , etc.

In particular, you can rewrite the for loop like this:

 for line in file: words = line.split() x[words[0]].append(words[1]) y[words[0]].append(words[2]) 
+5
source

You can use the globals() dictionary this way:

 x0=[] y0=[] x2=[] y2=[] x16=[] y16=[] # etc for line in file: words=line.split() x=globals()['x'+words[0]] y=globals()['y'+words[0]] x.append(words[1]) y.append(words[2]) 
0
source

Some people will scream, but I still do not understand why they are unhappy with the use of globals()

 for line in file: words=line.split() zx,zy = 'x%d' % words[0], 'y%d' % words[0] if zx not in globals(): globals()[zx] = [] globals()[zy] = [] globals()[zx].append(words[1]) globals()[zy].append(words[2]) 
0
source

Yes, you should use a dictionary. But to answer your question, you can use locals() or, more flexibly, compile the desired command and execute it with eval . For example, if your data is numeric:

 words = line.split() eval("x%s.append(%s)" % (words[0], words[1])) eval("y%s.append(%s)" % (words[0], words[2])) 

Note that line.split() gives you strings, even if they consist only of numbers. Therefore, %s , not %d .

But anyway, don't do it. Use a dict.

0
source

Source: https://habr.com/ru/post/1468793/


All Articles