简体   繁体   English

将用户输入字典添加到列表中; 只附加最后一个用户输入?

[英]Adding User Input Dicts Into a List; Only Appends Last User Input?

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.我正在尝试制作一个简单的 function 字典,其中字典是根据用户输入制作的,然后每次为每个键分配一个值时,它都会被附加到一个列表中。 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?所以它会 append 多个字典,但他们都说同样的话,我不知道为什么?

it is a refference issue, you're always appending the same dictionary instance and so on every step you're modifying that same instance.这是一个参考问题,您总是附加相同的字典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.这样, info变量在每一步都会被覆盖并获得一个新的 id,这应该可以满足您的需求。

here is a pretty good rundown of the issues that go along with this behaviour. 是 go 以及这种行为的问题的一个很好的概述。

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.只需创建一个 class 人这些对象然后有一个字典作为属性,或者名称.....作为属性。 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这只是一个基本提示,您的问题的解决方案已经记录在这里: https://stackoverflow.com/a/73134274/19238822

Hi this is happening because you assign info dicts keys inside loop.嗨,这是因为您在循环内分配了 info dicts 键。 So at assignment it changes current dictionary items values and append it.因此,在分配时,它会更改当前字典项的值和 append 它。 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.还将 print 放在循环执行的末尾,以便您可以监视已添加的值。

Hope this helps希望这可以帮助

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.您更改列表中每个元素的 id。

the most efficent is doing a copy using the builtin dict.copy() when you have to append;最有效的方法是使用内置的dict.copy()当你必须 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.好吧,当你 append 时你必须做一个副本,对于 rest 没关系,但我建议你只是while input("Would you like to add more to the dictionary? ").lower().startswith("y"):因为它更快,更不具体。

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警告:代码未经测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM