Im having some problems with structuring my for
loops. I want the numbers generated by random.randint
to be different for each settings list in every dictionary.
PopulationSize = 2
AmountofSettings = 5
key_index = '_index'
key_par = 'Fitness'
key_set = 'Settings'
data_set = [0] * PopulationSize
dict_per = {}
settings_per = [0] * AmountofSettings
These give the variables and names of the keys in every dictionary
for i in range(len(data_set)):
in this for-loop I am going through every dictionary in the list.
for x in range(len(settings_per)):
settings_per[x] = random.randint(0, 9)
I believe my problem is in this part. currently it constructs a list of 5 random integers, and assigns it to the 'Settings'
key in every dictionary. My goal is to have a new list in 'Settings'
in each dictionary.
dict_per = {key_index: i, key_par: None, key_set: settings_per}
data_set[i] = dict_per
print(data_set)
The data structure coming out is correct. However, every 'Settings'
list in the main dictionary list contains the same integers. I want the lists to be all different.
For extra clarity. This is the output right now for the data_list
. As you can see, the 'Settings'
are the same list of variables. I want the 'Settings'
lists to be different for every dict
.
Output right now:
[{'_index': 0, 'Fitness': None, 'Settings': [1, 7, 5, 4, 8]}, {'_index': 1, 'Fitness': None, 'Settings': [1, 7, 5, 4, 8]}]
But the output that I want:
[{'_index': 0, 'Fitness': None, 'Settings': [1, 7, 5, 4, 8]}, {'_index': 1, 'Fitness': None, 'Settings': [4, 6, 8, 1, 3]}]
where the second 'Settings'
list is independent of the first.
CodePudding user response:
Your problem is that you allocate Settings_per
once, then set the same reference for each new dict_per
that you make: key_set: Settings_per
.
You might think that dict_per
has the same issue, but it does not. Notice that in each iteration, you assign a new dictionary object to that name (dict_per = {...}
), despite the fact that you initialize it to an empty dictionary in the beginning.
Start by removing the unnecessary allocations at the beginning: dict_per
and Settings_per
. Create settings_per
properly in each iteration, as you do with dict_per
, rather than just filling it in.
Next, notice that dict_per
is being generated over and over, for each element of settings_per
. There is no need to do that. You only need to generate it once.
It is conventional to use snake_case for most variable and fuction names in python. CamelCase is generally used with user-defined class names. Constants are conventionally written as UPPERCASE_WITH_UNDERSCORES.
Here is what the code looks like with these changes:
POPULATION_SIZE = 2
SETTINGS_COUNT = 5
KEY_INDEX = '_index'
KEY_PAR = 'Fitness'
KEY_SET = 'Settings'
data_set = [None] * POPULATION_SIZE
for i in range(POPULATION_SIZE):
settings_per = [None] * SETTINGS_COUNT
for x in range(SETTINGS_COUNT):
settings_per[x] = random.randint(0, 9)
dict_per = {KEY_INDEX: i, KEY_PAR: None, KEY_SET: settings_per}
data_set[i] = dict_per
print(data_set)
The code above is already totally functional, but you can make it better. First satisfy yourself that you can rewrite the inner loop as follows:
settings_per = []
for x in range(SETTINGS_COUNT):
settings_per.append(random.randint(0, 9))
That's the idiomatic expanded equivalent for a list comprehension:
settings_per = [random.randint(0, 9) for _ in range(SETTINGS_COUNT)]
_
is often used to indicate a discarded loop variable.
Now you can write the entire outer loop as
data_set = [None] * POPULATION_SIZE
for i in range(POPULATION_SIZE):
data_set[i] = {KEY_INDEX: i, KEY_PAR: None, KEY_SET: [random.randint(0, 9) for _ in range(SETTINGS_COUNT)]}
Now the outer loop is beginning to loop just like the form of the inner loop that we converted to a list comprehension. And indeed, there is a dictionary comprehension syntax available as well:
data_set = {KEY_INDEX: i, KEY_PAR: None, KEY_SET: [random.randint(0, 9) for _ in range(SETTINGS_COUNT)] for i in range(POPULATION_SIZE)}
CodePudding user response:
Your mistake is at
for x in range(len(Settings_per)):
Settings_per[x] = random.randint(0,9) #replace for better initialization
dict_per= {key_index: i, key_par: None, key_set: Settings_per} # Here
which could be fixed by:
for i in range(len(data_set)):
for x in range(len(Settings_per)):
Settings_per[x] = random.randint(0,9)
dict_per= {key_index: i, key_par: None, key_set: Settings_per}
data_set[i] = dict_per