0

I have 100 lists :

l0 = [35.467, 1785387, 9984670,  0.913]
l1 = [63.951, 2833687, 640679,  0.888]
l2 = [80.940, 3874437, 357114,  0.916]
l3 = [60.665, 2167744, 301336,  0.873]
l4 = [127.061, 4602367, 377930,  0.891]
l5 = [64.511, 2950039, 242495,  0.907]
l6 = [318.523, 17348075, 9525067,  0.915]

I want to create it as a Numpy array of 100 rows and 4 columns. I am wondering if there's a way to pass the names of the list into the Numpy array function directly?

I have used for loop to create a list which then stores :
names_of_variables_in_a_list = ['l0,', 'l1,', 'l2,', 'l3,', 'l4,', 'l5,', 'l6,'....,'l99','l100']

But when I am trying to pass it like :
Employee_data = np.array(names_of_variables_in_a_list).
It's not working, could anyone know if this is possible?

lavalade
  • 329
  • 2
  • 11
  • 1
    Oh my God, WHY? I mean, why did you define 100 separate variables rather than just a single list of lists? – Błotosmętek Apr 25 '20 at 14:43
  • 3
    You can pass the lists themselves as in `arr = np.array([l0, l1, l2, l3, l4, l5, l6, l5])`. This produces a 6x4 Numpy array for example. – DarrylG Apr 25 '20 at 14:44
  • @Błotosmętek : I understand it looks naive, but the assignment that's been provided had these 100 lists already defined with names l0, l1, l2... – Navneet Kumar Apr 25 '20 at 15:20
  • @DarrylG : Yep, that's working absolutely fine. I had been wondering if there's a more optimised solution to it rather than typing 100 variables name if it's already in an order. – Navneet Kumar Apr 25 '20 at 15:21
  • @NavneetKumar--rather than using 100 variables the more typical approach is to have the data structure be either: 1) a list of lists, or 2) a dictionary. For instance, with a dictionary, you could have named your keys 'l0', to 'l100' with the corresponding data as values. – DarrylG Apr 25 '20 at 15:34

5 Answers5

1

How do you get those lists? Load from a file? copy-n-paste?

If copy-n-paste your sample to an ipython session, I can get a list of lists with:

In [866]: alist = [globals()[f'l{i}'] for i in range(0,6)]                                             
In [867]: alist                                                                                        
Out[867]: 
[[35.467, 1785387, 9984670, 0.913],
 [63.951, 2833687, 640679, 0.888],
 [80.94, 3874437, 357114, 0.916],
 [60.665, 2167744, 301336, 0.873],
 [127.061, 4602367, 377930, 0.891],
 [64.511, 2950039, 242495, 0.907]]
In [868]: np.array(alist)                                                                              
Out[868]: 
array([[3.546700e+01, 1.785387e+06, 9.984670e+06, 9.130000e-01],
       [6.395100e+01, 2.833687e+06, 6.406790e+05, 8.880000e-01],
       [8.094000e+01, 3.874437e+06, 3.571140e+05, 9.160000e-01],
       [6.066500e+01, 2.167744e+06, 3.013360e+05, 8.730000e-01],
       [1.270610e+02, 4.602367e+06, 3.779300e+05, 8.910000e-01],
       [6.451100e+01, 2.950039e+06, 2.424950e+05, 9.070000e-01]])

globals() is a dictionary of all variables currently defined in the session.

In [869]: globals()['l1']                                                                              
Out[869]: [63.951, 2833687, 640679, 0.888]

Using globals like this is similar to using exec

Providing a long list of variables like this is not good Python style. It's better to provide a list of the lists directly. If the source went to all the work of typing:

l0 = ...
11 = ...

they could also have provided alist = [l0, l1, ...] or entered a list of lists as I show in [876]

hpaulj
  • 221,503
  • 14
  • 230
  • 353
0

You can do this as

np.array([eval('l' + str(i)) for i in range(100)])

or if you want to use the list_of_names you already created,

np.array([eval(name) for name in list_of_names])

or as Vicrobot answered,

np.array(list(map(eval, list_of_names)))

All equivalent.

eval('var') returns the variable var, and there are other (safer) ways to do this, but it's probably fine here. The [... for i in range(100)] is a list comprehension that acts like a for-loop to create a list.

But I have to mention: it is very bad practice to name 100 separate variables like this, and also very bad practice to name variables using lowercase l.

stevemo
  • 1,077
  • 6
  • 10
  • Thanks Stevemo for adding the extra resources as well. This solution worked for me and I think it's the ideal solution for this problem. I was also wondering if there's a way to pass the list of variables names in the list and the answer provided by Vicrobot providing the combination of map and eval seems best in the general scenario if one has the list of variables stored in a list – Navneet Kumar Apr 25 '20 at 16:33
  • `list(map(eval, mylist))` is equivalent to `[eval(item) for item in mylist]` -- pick your poison! – stevemo Apr 25 '20 at 17:49
-1

You can pass a list of lists to np.array:

lol = [[1,2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
np.array(lol)

It looks like your names_of_variables_in_a_list is a list of strings and not a list of references to the list variables, though. You can use eval to get the actual variable instead of the string representation:

names_of_variables_in_a_list = eval("l"+str(i)) for i in range(1, 100)]
np.array(names_of_variables_in_a_list)

though eval really is not a generally advisable/safe thing to do. You're better off reconsidering making those 100 different variables. A dict where each key is the name and the value is the list might make this easier for you.

ZaxR
  • 4,896
  • 4
  • 23
  • 42
  • Thanks ZaxR. Sorry if you could expand on why eval shouldn't be used? Especially in scenarios where I know the variable names and it's not coming from an external file. – Navneet Kumar Apr 25 '20 at 16:37
  • There's a number of answers to this on SO, such as: https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice . The biggest issue in my mind is that eval will try to run ANYTHING you feed it. When it comes to data, if that data is read from an external file, it's possible that someone could put malicious "code" in the file. If this really is for a trivial case, and no one will have the ability to change the external data/python, eval is fine (albeit slow) - it's just not the best way to do it (in this case, probably the dict approach is "best") – ZaxR Apr 25 '20 at 19:38
-1

To embed the name of list, the natural way would be to use dictionary :

l0 = [35.467, 1785387, 9984670, 0.913]
l1 = [63.951, 2833687, 640679, 0.888]
l2 = [80.940, 3874437, 357114, 0.916]
l3 = [60.665, 2167744, 301336, 0.873]
l4 = [127.061, 4602367, 377930, 0.891]
l5 = [64.511, 2950039, 242495, 0.907]
l6 = [318.523, 17348075, 9525067, 0.915]

d = {}
for i in range(7):
    d['l{:d}'.format(i)] = eval('l{:d}'.format(i))

then the result is

In [2]: d
Out[2]:
{'l0': [35.467, 1785387, 9984670, 0.913],
 'l1': [63.951, 2833687, 640679, 0.888],
 'l2': [80.94, 3874437, 357114, 0.916],
 'l3': [60.665, 2167744, 301336, 0.873],
 'l4': [127.061, 4602367, 377930, 0.891],
 'l5': [64.511, 2950039, 242495, 0.907],
 'l6': [318.523, 17348075, 9525067, 0.915]}

Shorter with dictionary comprehension :

d = {'l{:d}'.format(i): eval('l{:d}'.format(i)) for i in range(7)}

and even shorter with f-string (python >= 3.6) :

d = {f'l{i}': eval(f'l{i}') for i in range(7)}

If you want to create an numpy ndarray without keeping the name of list :

import numpy as np
array2d = np.array([eval('l{}'.format(i)) for i in range(7)])

then the result is

In [4]: array2d
Out[4]:
array([[3.5467000e+01, 1.7853870e+06, 9.9846700e+06, 9.1300000e-01],
       [6.3951000e+01, 2.8336870e+06, 6.4067900e+05, 8.8800000e-01],
       [8.0940000e+01, 3.8744370e+06, 3.5711400e+05, 9.1600000e-01],
       [6.0665000e+01, 2.1677440e+06, 3.0133600e+05, 8.7300000e-01],
       [1.2706100e+02, 4.6023670e+06, 3.7793000e+05, 8.9100000e-01],
       [6.4511000e+01, 2.9500390e+06, 2.4249500e+05, 9.0700000e-01],
       [3.1852300e+02, 1.7348075e+07, 9.5250670e+06, 9.1500000e-01]])

where array2d[i,:] is list i-th list.
And the shorter way with f-string (python >= 3.6) :

array2d = np.array([eval(f'l{i}') for i in range(7)])
lavalade
  • 329
  • 2
  • 11
  • 1
    Thanks Leaurendmalade. This whole thing is useful, I was more interested in Numpy array related solution but dictionaries def seem to be a great alternative to store this kind of data. – Navneet Kumar Apr 25 '20 at 16:33
-2

You can use eval function:

>>> l0=[1,2,3]
>>> l1=[2,4,6]
>>> np.asarray(list(map(eval, ['l0','l1'])))
array([[1, 2, 3],
       [2, 4, 6]])
Vicrobot
  • 3,795
  • 1
  • 17
  • 31
  • This solution worked the best for me, I could just pass the list which had the names stored. The combination of map and eval is probably what I was looking for me. Thanks! Would you know why it's been marked as not useful (I didn't do it)? Are there any specific caveats to this solution? – Navneet Kumar Apr 25 '20 at 16:34
  • @NavneetKumar I don't see any. You can accept the answer if it helps you. – Vicrobot Apr 26 '20 at 13:21