1

before you all tell me to search for stuff, let me tell you "I HAVE".

I have searched quite a bit. Forums, educational/training sites, stackexchange and all the regulars. I haven't been able to get what I need. I am not running to SE at the first sign of trouble either. I have registered on SE quite a while ago and this is my first question.

I have found some replies(suggestions, not solutions) and some ANSWERS(sort of) too. However, the most useful thing I have found is https://stackoverflow.com/a/6181978/15065496

I do know what dictionaries are, I know how to use them. I have tried the answer above too, but it isn't exactly what I want.

I am a mechanical engineer learning python to solve some engineering problems that I am having. Please read till the end to get a better idea of what I am trying to achieve.

I need to create a list of lists with names. I have been able to create a list of lists, which looks like this:

list_xyz = []
for i in range(1,5,1):
    temp_array_name = "list_" + str(i)
    list_xyz.append(temp_array_name)

>>> list_xyz
['list_1', 'list_2', 'list_3', 'list_4']

Now, I want to create a new list out of each of the elements.

Basically, what I want is to create lists called list_1, list_2, list_3, list_4. I want to automate the task of doing

list_1 = []
list_2 = []
list_3 = []
list_4 = []

what I have already tried are:

for i in list_xyz:
    i = list()

*this gives:*

>>> list_xyz
['list_1', 'list_2', 'list_3', 'list_4']

*I thought good*. Then I typed:

>>> list_1

*I was expecting the following *
[]

*Instead, I got:*
Traceback (most recent call last):
  File "<pyshell#93>", line 1, in <module>
    list_1
NameError: name 'list_1' is not defined


*Then I tried the following and understood what had happened.*
>>> i
[]

*So then, I tried:*

for i in range(0,len(list_xyz),1):
    list_xyz[i] = list()

*this gave:*

>>> list_xyz
[[], [], [], []]


Now, technically I could use the elements of list_xyz, but calling them would be a pain. If I need the third element inside the second element of list_xyz, then I would have to say list_xyz[1][2]

Instead, if they were named, I could just say list_2[2] and could get the element I was looking for.

I have also tried using dictionaries, as suggested by https://stackoverflow.com/users/455276/the-wolf in https://stackoverflow.com/a/6181978/15065496.

What I have tried is:

>>> dict1 = {}
>>> list_pqr = ['list_1', 'list_2', 'list_3', 'list_4']
>>> for i in range(0,len(list_pqr),1):
    dict1[list_pqr[i]] = list()

    
>>> dict1
{'list_3': [], 'list_2': [], 'list_1': [], 'list_4': []}

This is close to what I want but isn't exactly what I want. Please read the following to understand exactly what I want.

The reason I need this particular list this exact way is: I am trying to calculate some temperatures at different times at different positions. I want to create a dictionary with times as keys and a list of temperatures at various locations as the values.

and another dictionary with locations as keys and list temperatures at different times as the values.

What I want is:

dict1 = {time1: temps_at_time_1
time2: temps_at_time_2
time3: temps_at_time_3
time4: temps_at_time_4
time5: temps_at_time_5
}

dict2 = {loc1: temps_at_times_L1
loc2: temps_at_times_L2
loc3: temps_at_times_L3
loc4: temps_at_times_L4
loc5: temps_at_times_L5
}

where temps_at_times_L1 is the list of temperatures at location 1 at various times. where temp_at_time_1 is the list of temperatures at Time 1 at various locations.

let's say there are 25 locations and 100 timesteps, then:

len(temps_at_times_L1) = 100
len(temp_at_time_1) = 25

now, if temps_at_times_L1 and temp_at_time_1 are variables that I could call, It would make it very easy for me to plot the temperatures etc.

Basically, I want the same thing that I have achieved with dictionaries after using the wolf's suggestion, but the lists created there should have names that I could call so that when calculating temperatures, I could just update the lists by calling the append() method. If I am calculating timestep1, I wanna be able to just say:

while(timestep == 1):
   for i in temperature_location_array:
       temps_at_time_1.append(i)

Even better would be if i was able to do the following:

for a in range(startTime, endTime, stepSize):
while(timestep == a):
   for i in temperature_location_array:
       temps_at_time_a.append(i)       or      vars("temps_at_time_" + str(a)).append(i)

I'm pretty sure the last line will not work and I will have to rack my brains again for that. I have tried reading about how vars() works but it is giving me a headache.

If you guys can't help me, and/or tell me that the last line of my code is stooooopid, then I'll just have to make do with the basic dictionary and ridiculously complicated(for my level anyway) indexing and calling and assigning directly to the values dictionaries.

I have previously faced the same need whilst editing a spreadsheet using openpyxl, but was unable to create lists from variable names inside another list. I gave up and used another method that got the job done. However, this time I would like to know how to do it: if at all it can be done.

Thank you all for the trouble of reading through my long winded explanation. I did this so people who reply will understand exactly what I need and will not give suggestions that would not serve my purpose. I will read all suggestions and take all useful ones into account though. I am not trying to offend/insult anyone.

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158
  • 2
    I have two comments: The first is that using some sort of data analysis framework like Pandas may simplify your taks greatly, if it's possible to use. The second is in regards to your actual question, you can check out [this post](https://stackoverflow.com/questions/4859217/programmatically-creating-variables-in-python) on how to programatically set variable names. – bicarlsen Jul 27 '21 at 10:06
  • 2
    Are you allowed to use other libraries? `pandas` comes to mind, because you basically have 2 axis, 25 locations (y axis) and 100 temperatures (x axis). Otherwise a nested dictionary might help, such as: `dct = {'location_1': {'temp1': 10, 'temp2': 11}}` get values like this: `dct['location_1']['temp2']` which will return `11`. Btw. setting variables dynamically is nearly never what you actually want, I think also not in this case. – Andreas Jul 27 '21 at 10:07
  • 3
    If you have similar variables (ie you want to give them similar names, as in your `list1`, `list2`...) then it is a very strong sign that you need to organize them in a larger structure, rather than having them related by names. Iterating and indexing are easy this way. Using `'list' + str(i)` everytime isn't. So, a dict, a list... whatever. If you really want to manipulate a part of it without writing things like `list_xyz[1][2]`, just set `mylist = list_xyz[1]` and use `mylist[2]`. – Thierry Lathuille Jul 27 '21 at 10:22
  • bicarlsen, Andreas and Thierry Lathuille : Thank you all for answering. I am allowed to use other libraries. I do not know pandas. I will familiarise myself with it. Based on what Andreas said( _2 axis_ ), It got me thinking if it would be possible to achieve the same thing using a 2D numpy array.(Will investigate). I liked the Idea of nested dictionaries a lot but given that there are going to be many many sets of data(27 multiple locations and over 3000 timesteps), I don't think manually creating nested dictionaries will help. Again, trying to do it programatically is discouraged. – Chandradhar Koneti Jul 27 '21 at 11:20
  • I liked the trick @ThierryLathuille said. Simply assign `mylist = list_xyz[1]` and use `mylist[2]` Since everyone is discouraging the use of programatically creating variable names, I will try to use numpy or pandas and a 2D array or table. Thank you all. – Chandradhar Koneti Jul 27 '21 at 11:23

2 Answers2

3

Sorry for the negativity but appending numbers to variables is the exact opposite what any programmer should be doing - nested_lists[1][2] is the correct way of handling nested lists, nested_list_1[2] is not. Do not write data into the names of variables, just don't, it won't end well and globals() is terrible misuse here.

What you need is some proper structure that will give meaning to your data. I would recommend pandas library. It's like Excel for Python.

Let's take the following example of 5 measurements in two locations foo and bar at various times.

# Assuming the raw data is in format:
#  (time, temperature, location)
import pandas as pd
data=pd.DataFrame({
    (1,12, 'foo'),
    (2,12,'bar'),
    (10,23,'foo'),
    (3,12,'foo'),
    (3,15,'bar')
    },columns=['time','temperature','location'])
print(data)

yields:

   time  temperature location
0     1           12      foo
1     2           12      bar
2     3           15      bar
3    10           23      foo
4     3           12      foo

I cannot enumerate all the things you can do with a dataframe but it can be sorted, filtered, mapped, indexed... see the documentation or search for answers here.

You might be interested in e.g. filtering data by location data[data['location']=='foo']

   time  temperature location
0     1           12      foo
3    10           23      foo
4     3           12      foo

or setting the dataframe's index to time column and indexing using it:

new_data = data.set_index('time')
print(new_data.loc[3])
      temperature location
time                      
3              15      bar
3              12      foo
Quimby
  • 17,735
  • 4
  • 35
  • 55
  • WOW!!!! Thanks a LOT for that reply. It basically solved my problems. I just need to familiarise myself with pnadas now. The contributors at the top of this post have also been suggesting pandas but *THANK YOU* for explaining how to go about doing it. Is pandas easy to work with? I mean can I use methods/functions similar to append, del etc etc??(insert Dr.Strange _Teach me_ meme here) – Chandradhar Koneti Jul 27 '21 at 11:34
  • 1
    @ChandradharKoneti I would not call it easy since the API is really large, but you can always google "pandas how to do X" and click on stackoverflow ;). Its documentation is also very good. So, prepare for a lot of googling and reading but it is so much worth it. Processing data without pandas would be much harder anyway. – Quimby Jul 27 '21 at 14:16
  • I started leaning pandas. Will post the solution(as close as I can get it) to my question after I get it to work. – Chandradhar Koneti Jul 31 '21 at 08:19
  • 1
    czeni's answer answers my question **TO THE POINT**, **_BUT_** your answer is better for me in the long run. **My request to any future readers of this question is to learn Pandas or use Dictionaries.** I have started to learn Pandas and I must say, **PANDAS is WAY EASIER and SIMPLER** than programmatically creating variable names. Although I must admit, programatically creating variable names is the first thing that come to mind for a long time **_EXCEL_** user, even after learning PANDAS and learning to better utilise dictionaries. Gotta get rid of that habit. – Chandradhar Koneti Sep 14 '21 at 12:48
  • @ChandradharKoneti Glad to hear that you like pandas :) – Quimby Sep 14 '21 at 13:11
1

As several commenters are mentioned before me you actually can create variables programatically, but is a very ugly way of solving a problem.

Anyway, you can add variables to the global namespace with globals() as follows:

>>> list_xyz
['list_1', 'list_2', 'list_3', 'list_4']
>>> for n in list_xyz:
...     globals()[n] = list()
... 
>>> list_1
[]
>>> list_2
[]
>>> list_3
[]
>>> list_4
[]
>>> 
czeni
  • 427
  • 2
  • 11
  • Thank you very much for the answer. I really liked that solution. **IT WORKED**. Could you also please take a look at the last line of the last code block. `vars("temps_at_time_" + str(a)).append(i)`. I know that 'as written', it will fail. If you could guide me on how to achieve that, I would be very happy. I liked your solution a lot, but given that _you and everyone else_ is discouraging creating variables programmatically, I will try to shun that practice. :) Thanks for answering. – Chandradhar Koneti Jul 27 '21 at 11:05
  • 2
    @ChandradharKoneti Similarly, as `globals()` returns a dict-like structure, so does `vars()`. What you want is `vars()["temps_at_time_" + str(a)].append(i)`, but use this only as the last-last-last resort :) – czeni Jul 27 '21 at 12:21
  • Thank you very very much. :) – Chandradhar Koneti Jul 27 '21 at 12:46
  • **YOUR ANSWER** answers my question **TO THE POINT**, **_BUT_** Quimby's answer is better for me in the long run. **My request to any future readers of this question is to learn Pandas or use Dictionaries.** I have started to learn Pandas and I must say, **PANDAS is WAY EASIER and SIMPLER** than programmatically creating variable names. Although I must admit, programatically creating variable names is the first thing that come to mind for a long time **_EXCEL_** user, even after learning PANDAS and learning to better utilise dictionaries. Gotta get rid of that habit. – Chandradhar Koneti Sep 14 '21 at 12:47