0

I've been trying to find a way to create variables from within a for loop without needing to know in advance how many variables I will need to create. I've run into examples such as:

a_dictionary = {}
for number in range(1,4):
    a_dictionary["key%s" %number] = "abc"

print(a_dictionary)
{'key1': 'abc', 'key2': 'abc', 'key3': 'abc'}

Another I have seen is

d={}
for x in range(1,10):
    d["string{0}".format(x)]="Variable1"

print(d)
{'string1': 'Variable1', 'string2': 'Variable1','string3': 'Variable1', 'string4': 'Variable1', 'string5':'Variable1', 'string6': 'Variable1', 'string7': 'Variable1','string8': 'Variable1', 'string9': 'Variable1'}

My question is, how does this work, and is there a way to do something similar, like global variables without the need for a dictionary? For example, to do something like

random_list = [23,67,12,93,5,420]
for i in range(0,6):
    variable_i = random_list[i]
    print(variable_i)

23
67
12
93
5
420

to achieve the same thing as a manual assignment such as

variable_0 = 23
variable_1 = 67
variable_2 = 12
variable_3 = 93
variable_4 = 5
variable_5 = 420
  • 4
    You don't EVER want to create globals like that. If you don't know how many variables there will be, how will you refer to them? Use a dictionary. **That's what they're for.** As a general rule, any code that tweaks with `globals()` is badly designed. – Tim Roberts Apr 21 '22 at 20:33
  • 1
    A dictionary is just a mapping from a key to a value. Just that simple. The keys can be anything that can be hashed, but very often are strings. The strings can either be constants or variables, as in your example. – Tim Roberts Apr 21 '22 at 20:34
  • 1
    What is the reason behind not allowing a dictionary to contain key values for the example you've provided at the end? i.e. `{'variable_0': 23, 'variable_1': 67}` – Simon Apr 21 '22 at 20:34
  • "how does this work" - it inserts new key-value pairs into the dictionary. Holding key-value pairs is basically the main and only point of dictionaries, that's what they're designed to do. – ForceBru Apr 21 '22 at 20:35
  • "My question is, how does this work, and is there a way to do something similar, like global variables without the need for a dictionary?" **you shouldn't be dynamically creating variables**. You *can* do this in CPython in global scopes, but that just amounts to *working with a dictionary*, i.e. the global namespace, which is just a regular dict object. But you *shouldnt*. Note, if you *do* end up doing this, you'll just end up working with the `globals()` dictionary anyway. The proper way to do this is just *to use your own `dict`* – juanpa.arrivillaga Apr 21 '22 at 20:41

1 Answers1

1

The module namespace is a dictionary and you can get it via globals(). Using f-strings (the newest way to build strings from variables) and the enumerate function instead of range, you could

>>> random_list = [23,67,12,93,5,420]
>>> for i, val in enumerate(random_list):
...     globals()[f"variable_{i}"] = val
... 
>>> variable_0
23

The for can be replaced by using the dictionary's "update" method

globals().update((f"variable_{i}", val) for i, val in enumerate(random_list))
tdelaney
  • 73,364
  • 6
  • 83
  • 116
  • 2
    This is an absolutely terrible idea. – MattDMo Apr 21 '22 at 20:41
  • 1
    @MattDMo it can be worse if you do that with `exec()`))))) – sudden_appearance Apr 21 '22 at 20:44
  • @MattDMo - there are perfectly legitimate reasons to put variables into the global namespace and legitimate reasons why you might want to auto-generate them. The poster doesn't tell us why this is being done, so its hard to say in this case. – tdelaney Apr 21 '22 at 21:06
  • @sudden_appearance - I don't understand, I didn't use exec in the example. – tdelaney Apr 21 '22 at 21:07
  • 1
    Yes, I know `globals()` is writeable for a reason, I just think that 99% of the (inexperienced) programmers out there who want to create dynamic variables don't need to, and should be encouraged as much as possible to use dicts instead. I didn't downvote your answer, as it is correct, I'd just suggest adding a nice big warning with a clear example along with what you wrote. Also, this question is a perfect dupe of the one I tagged, so ideally you should have flagged it for closure, if you knew about the dupe already. And if you didn't, now you do :) – MattDMo Apr 21 '22 at 22:14