I'm trying to make a simple function where a dictionary is made from user input, then every time every key is assigned a value, it gets appended to a list. This is my code:
info = {}
people = []
add = input("Would you like to add info to a dictionary? ").lower()
while add == "yes":
info["Name"] = input("Who would you like to add to the dict? ").title()
info["Language"] = input("What language do they speak? ").title()
info["Game"] = input("What is their favoriate game? ").title()
people.append(info)
add = input("Would you like to add more to the dictionary? ").lower()
If I add multiple entries, it only appends the last sequence the user inputs. So it will append multiple dictionaries, but they all say the same thing, and I'm not sure why?
CodePudding user response:
Hi this is happening because you assign info dicts keys inside loop. So at assignment it changes current dictionary items values and append it. To fix it after each appending each item you need to empty dictionary as below
info = {}
people = []
add = input("Would you like to add info to a dictionary? Yes/No:").lower()
while add == "yes":
info["Name"] = input("Who would you like to add to the dict? ").title()
info["Language"] = input("What language do they speak? ").title()
info["Game"] = input("What is their favoriate game? ").title()
people.append(info)
# here we empty the info dictionary so next time loop runs it starts empty
info = {}
print(people)
add = input("Would you like to add more to the dictionary? ").lower()
Also put print at the end of loop execution so you can monitor values you've added.
Hope this helps!
CodePudding user response:
it is a refference issue, you're always appending the same dictionary instance
and so on every step you're modifying that same instance.
try this instead:
people = []
add = input("Would you like to add info to a dictionary? ").lower()
while add == "yes":
info = {}
info["Name"] = input("Who would you like to add to the dict? ").title()
info["Language"] = input("What language do they speak? ").title()
info["Game"] = input("What is their favoriate game? ").title()
people.append(info)
add = input("Would you like to add more to the dictionary? ").lower()
in this way, the info
variable gets overwritten at each step and gets a new id, this should do what you want.
here is a pretty good rundown of the issues that go along with this behaviour.
CodePudding user response:
Of course, I don't know the connection here, but what would make sense here would be to pack the "people" into objects. Just create a class people These objects then have a dictionary as an attribute, or the name..... as attributes. You can then still bundle these objects in a list. So you are generally more flexible.
This is just a basic tip, the solution to your problem has already been recorded here: https://stackoverflow.com/a/73134274/19238822
CodePudding user response:
What is the problem?
It's a reference issue, you're always appending the same dictionary instance and so on every step, every time modifying that same instance.
you can see that just by printing gradually the list:
[{"Name":"James","Language":"English","Game":"World of Worldcraft"}]
[{"Name":"Marcus","Language":"Spanish","Game":Minecraft},{"Name":"Marcus","Language":"Spanish","Game":Minecraft}]
...
How can i fix it?
Well, there are some ways you can achieve that but you always achieve the same result:
You change the id of every element of the list.
the most efficent is doing a copy using the builtin dict.copy()
when you have to append; here is a sample code to do this:
>>> c = {}
>>> id(c)
1908947910016
>>> id(c.copy()) #different from id(c)
1908947910272
What should be the code in your case?
Well, when you append you have to do a copy, for the rest it's ok, but i'll suggest you to just do while input("Would you like to add more to the dictionary? ").lower().startswith("y"):
because it's faster and less specific.
Here is the code:
people = []
info = {}
add = input("Would you like to add info to a dictionary? ").lower()
while input("Would you like to add more to the dictionary?").lower().startswith("y"):
info["Name"] = input("Who would you like to add to the dict? ").title()
info["Language"] = input("What language do they speak? ").title()
info["Game"] = input("What is their favoriate game? ").title()
people.append(info.copy())
WARNING:The code is not tested!