Appending to pre-populated list within a dictionary of lists alters all lists within dictionary
Question:
I’m attempting to sort some values into a dictionary of lists using string prefixes. Here is the basic code I am running:
values = ["a_one", "a_two", "b_three", "b_four", "c_five", "c_six"]
value_groups = {"a": [],
"b": [],
"c": []}
for value in values:
for prefix in value_groups.keys():
if value.startswith(prefix):
value_groups[prefix].append(value)
break
The desired, and actual, output of this code is:
value_groups = {"a": ["a_one", "a_two"],
"b": ["b_three", "b_four"],
"c": ["c_five", "c_six"]}
So the code above works as-is.
My problem arises when I initialize the lists within value_groups
with one or more strings. In this case, every value
in values
gets appended to every list within value_groups
. Non-functional code below:
values = ["a_one", "a_two", "b_three", "b_four", "c_five", "c_six"]
# ---START OF EDITED CODE---
initial_list = ["x", "y", "z"]
value_groups = {"a": initial_list,
"b": initial_list,
"c": initial_list}
# ---END OF EDITED CODE---
for value in values:
for prefix in value_groups.keys():
if value.startswith(prefix):
value_groups[prefix].append(value)
break
The desired output of this code would be:
value_groups = {"a": ["x", "y", "z", "a_one", "a_two"],
"b": ["x", "y", "z", "b_three", "b_four"],
"c": ["x", "y", "z", "c_five", "c_six"]}
But instead, I am getting three identical lists within value_groups
:
value_groups = {"a": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"],
"b": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"],
"c": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"]}
My intuition (and preliminary Stack Overflow research) is that there is some sort of memory referencing mechanism that I am running afoul of, but I am not quite sure what it is. Anyone out there able to explain it to me? (if that is, indeed, the problem…)
Answers:
value_groups = {"a": ["x", "y", "z"],
"b": ["x", "y", "z"],
"c": ["x", "y", "z"]}
I’m pretty certain that’s not how you’re defining value_groups
. What you’ve probably done is something like this (where some_list
was previously defined):
some_list = ["x", "y", "z"]
value_groups = {"a": some_list,
"b": some_list,
"c": some_list}
If that’s the case, every key in the dict refers to the same list. A fix would be to make copies of some_list
using some_list.copy()
(or by copying with an empty slice some_list[:]
):
some_list = ["x", "y", "z"]
value_groups = {"a": some_list.copy(),
"b": some_list.copy(),
"c": some_list.copy()}
I’m attempting to sort some values into a dictionary of lists using string prefixes. Here is the basic code I am running:
values = ["a_one", "a_two", "b_three", "b_four", "c_five", "c_six"]
value_groups = {"a": [],
"b": [],
"c": []}
for value in values:
for prefix in value_groups.keys():
if value.startswith(prefix):
value_groups[prefix].append(value)
break
The desired, and actual, output of this code is:
value_groups = {"a": ["a_one", "a_two"],
"b": ["b_three", "b_four"],
"c": ["c_five", "c_six"]}
So the code above works as-is.
My problem arises when I initialize the lists within value_groups
with one or more strings. In this case, every value
in values
gets appended to every list within value_groups
. Non-functional code below:
values = ["a_one", "a_two", "b_three", "b_four", "c_five", "c_six"]
# ---START OF EDITED CODE---
initial_list = ["x", "y", "z"]
value_groups = {"a": initial_list,
"b": initial_list,
"c": initial_list}
# ---END OF EDITED CODE---
for value in values:
for prefix in value_groups.keys():
if value.startswith(prefix):
value_groups[prefix].append(value)
break
The desired output of this code would be:
value_groups = {"a": ["x", "y", "z", "a_one", "a_two"],
"b": ["x", "y", "z", "b_three", "b_four"],
"c": ["x", "y", "z", "c_five", "c_six"]}
But instead, I am getting three identical lists within value_groups
:
value_groups = {"a": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"],
"b": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"],
"c": ["x", "y", "z", "a_one", "a_two",
"b_three", "b_four", "c_five", "c_six"]}
My intuition (and preliminary Stack Overflow research) is that there is some sort of memory referencing mechanism that I am running afoul of, but I am not quite sure what it is. Anyone out there able to explain it to me? (if that is, indeed, the problem…)
value_groups = {"a": ["x", "y", "z"],
"b": ["x", "y", "z"],
"c": ["x", "y", "z"]}
I’m pretty certain that’s not how you’re defining value_groups
. What you’ve probably done is something like this (where some_list
was previously defined):
some_list = ["x", "y", "z"]
value_groups = {"a": some_list,
"b": some_list,
"c": some_list}
If that’s the case, every key in the dict refers to the same list. A fix would be to make copies of some_list
using some_list.copy()
(or by copying with an empty slice some_list[:]
):
some_list = ["x", "y", "z"]
value_groups = {"a": some_list.copy(),
"b": some_list.copy(),
"c": some_list.copy()}