1

Is there any possibility of creating a list of variables/names* that have not been defined yet, and then loop through the list at a later stage to define them?

Like this:

varList = [varA, varB, varC]
for var in varList:
    var = 0
print(varList)

>>>[0, 0, 0]

The reason I'm asking is because I have a project where I could hypothetically batch fill 40+ variables/names* this way by looping through a Pandas series*. Unfortunately Python doesn't seem to allow undefined variables in a list. Does anyone have a creative workaround?

EDIT: Since you asked for the specific problem, here goes:

I have a Pandas series that looks like this (excuse the Swedish):

print(Elanv)

>>>
Förb. KVV PTP                 5653,021978
Förb. KVV Skogsflis                     0
Förb. KVV Återvinningsflis    337,1416119
Förb. KVV Eo1                         6,1
Förb. HVC Återvinningsflis           1848
Name: Elanv, dtype: object

I want to store each value in this array to a set of new variables/names*, the names of which I want to control. For example, I want the new variable/name* containing the first value to be called "förbKVVptp", the second one "förbKVVsflis", and so forth.

The "normal" option is to assign each variable manually, like this:

förbKVVptp, förbKVVsflis, förbKVVåflis = Elanv.iloc[0], Elanv.iloc[1], Elanv.iloc[2] .... 

But that creates a not so nice looking long bunch of code just to name variables/names*. Instead I thought I could do something like this (obviously with all the variables/names*, not just the first three) which looks and feels cleaner:

varList = [förbKVVptp, förbKVVsflis, förbKVVåflis]
for i, var in enumerate(varList): var = Elanv.iloc[i]

print(varList)

>>>[5653,021978, 0, 337,1416119]

Obviously this becomes pointless if I have to write the name of my new variables/names* twice (first to define them, then to put them inside the varList) so that was why I asked.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
Daniel Slätt
  • 751
  • 2
  • 15
  • 28
  • 3
    No. You do not define variables in Python. To be precise, there are **no** *variables* in Python. Only "names" which serve as references to objects – DeepSpace Oct 23 '18 at 10:54
  • `looping through a Pandas array`. What's a Pandas array? Pandas is designed to *avoid* Python-level loops. – jpp Oct 23 '18 at 10:56
  • 7
    This is an [XY problem](http://xyproblem.info). Ask about your problem, not an attempted solution – DeepSpace Oct 23 '18 at 10:57
  • Your problem still isn't clear to me after your edit. Are you trying to create a bunch of variables, or a list? – Aran-Fey Oct 23 '18 at 11:28
  • Sorry for that. The list is just the method for trying to create the bunch of variables (so that I can loop through them). – Daniel Slätt Oct 23 '18 at 11:33
  • Related, possibly duplicate: [Creating new variables in loop, with names from list, in Python](//stackoverflow.com/q/11319909) – Aran-Fey Oct 23 '18 at 11:37
  • BTW, you may find this article helpful: [Facts and myths about Python names and values](http://nedbatchelder.com/text/names.html), which was written by SO veteran Ned Batchelder. – PM 2Ring Oct 23 '18 at 11:45

3 Answers3

6

You cannot create uninitialized variables in python. Python doesn't really have variables, it has names referring to values. An uninitialized variable would be a name that doesn't refer to a value - so basically just a string:

varList = ['förbKVVptp', 'förbKVVsflis', 'förbKVVåflis']

You can turn these strings into variables by associating them with a value. One of the ways to do that is via globals:

for i, varname in enumerate(varList):
    globals()[varname] = Elanv.iloc[i]

However, dynamically creating variables like this is often a code smell. Consider storing the values in a dictionary or list instead:

my_vars_dict = {
    'förbKVVptp': Elanv.iloc[0],
    'förbKVVsflis': Elanv.iloc[1],
    'förbKVVåflis': Elanv.iloc[2]
}

my_vars_list = [Elanv.iloc[0], Elanv.iloc[1], Elanv.iloc[2]]

See also How do I create a variable number of variables?.

Aran-Fey
  • 39,665
  • 11
  • 104
  • 149
  • 1
    As suspected! Thank you, this is the answer I was looking for! Now I have both the option to go smelly code, or just do it the more pythonic way. – Daniel Slätt Oct 23 '18 at 11:53
2
  • The answer to your question is that you can not have undefined variables in a list.
  • My solution is specific to solving this part of your problem The reason I'm asking is that I have a project where I could hypothetically batch fill over 100 arrays this way by looping through a Pandas array.
  • Below solution prefills the list with None and then you can change the values in the list.

Code:

varList = [None]*3
for i in range(len(varList)):
    varList[i] = 0
print(varList)  

Output:
[0, 0, 0]

Rarblack
  • 4,559
  • 4
  • 22
  • 33
Jai
  • 3,211
  • 2
  • 17
  • 26
  • 6
    Why even bother with creating a list with 3 `None` and then setting them to 0? just do `[0] * 3` – DeepSpace Oct 23 '18 at 10:55
  • 3
    I just answered the question... He wanted like that so I did it – Jai Oct 23 '18 at 10:56
  • 1
    @DeepSpace Because the question specifically asked whether it was possible to create a list of variables that had not been defined, that could be set to 0 later. – Andrew McDowell Oct 23 '18 at 10:57
  • 2
    @AndrewMcDowell Setting something to `None` does not mean it "had not been defined". It means that it had been defined and set to `None`. – DeepSpace Oct 23 '18 at 10:59
  • 3
    @AndrewMcDowell More over, the answer to the question is **no**. This answer suggests that it is possible, which is wrong. – DeepSpace Oct 23 '18 at 11:00
  • 1
    @DeepSpace I understand the distinction, but it's possible that OP may want to iterate through and update entries that had not been initialised to an integer value yet. If 0 is a valid entry then setting the list to all 0's initially will not be helpful. I understand that the question could be improved, but as worded, I think this answer addresses the intent of the question best, – Andrew McDowell Oct 23 '18 at 11:02
  • @AndrewMcDowell Well, SO is not about speculating what OP might have meant, and I truly don't understand why this answer keeps getting up-voted. Not only it is the wrong answer, it is also not the best performing one. – DeepSpace Oct 23 '18 at 11:05
  • for instance `range(len(varList))` is an anti-pattern in python – Jean-François Fabre Oct 23 '18 at 11:06
  • 1
    @DeepSpace ... Look at the question properly... He's trying to do something and I am helping him achieve that... I know what he's trying to do and hence I answered how he can achieve it... He wants to achieve it by doing something which is not possible so I showed him the right way to achieve it – Jai Oct 23 '18 at 11:11
  • @Jai The question is `"Is there any possibility of creating a list of variables that have not been defined yet"` to which the answer is `"no"`. Regarding the example, you can get this output by doing `[0] * 3`, `[1 - 1, 2 - 2, 3 - 3]` and infinitely many other ways. It does not mean that these ways are the answer to the question – DeepSpace Oct 23 '18 at 11:12
  • 1
    @DeepSpace... I think you should change your mindset and stop being so harsh to people... And the reason why I am getting upvotes is that other people don't think like you – Jai Oct 23 '18 at 11:18
  • @Jai I was going to reply to you, then noticed you have some respect issues. Welcome to the Internet, where people don't have to agree with you. Have a nice day. – DeepSpace Oct 23 '18 at 11:20
  • 2
    Updated the question, guys. Thanks for showing interest, and sorry for not giving you the specific problem. Please be kind to one another! – Daniel Slätt Oct 23 '18 at 11:22
-2

So something you are trying to do in your example that won't do what you expect, is how you are trying to modify the list:

for var in varList:
    var = 0

When you do var = 0, it won't change the list, nor the values of varA, varB, varC (if they were defined.)

Similarly, the following won't change the value of the list. It will just change the value of var.

var = mylist[0]
var = 1

To change the value of the list, you need to do an assignment expression on an indexed item on the list:

mylist = [None, None, None]
for i in range(len(mylist)):
    mylist[i] = 0

print(mylist)

Note that by creating a list with empty slots before assigning the value is inefficient and not pythonic. A better way would be to just iterate through the source values, and append them to a list, or even better, use a list comprehension.

Gary van der Merwe
  • 9,134
  • 3
  • 49
  • 80