【问题标题】:Creating a list of dictionaries with same keys? [duplicate]创建具有相同键的字典列表? [复制]
【发布时间】:2019-03-12 05:02:00
【问题描述】:

我想创建一个列表,其中包含 x 个字典,所有字典都包含相同的键但具有不同的值,这些值在 for 循环中生成:

类似

[{'name': Brenda, 'Age': 22, 'Sex': Female},
 {'name': Jorda, 'Age': 32, 'Sex': Male},
 {'name': Richard, 'Age': 54, 'Sex': Male}]

我的代码是这样的:

people = []
person = {}

humans = gethumans()

for human in humans:
    number_people, people_data = People.data()
    person['name'] = human.name
    person['age'] = human.age
    person['Sex'] = human.name
    people.append(person)

我的输出是这样的:

[{'name': Richard, 'Age': 54, 'Sex': Male},
 {'name': Richard, 'Age': 54, 'Sex': Male}
 {'name': Richard, 'Age': 54, 'Sex': Male}]

由于字典值被替换而不是添加,它只是附加了同一个字典。我该如何解决这个问题?

【问题讨论】:

  • gethumans 在这里做什么?
  • 它是伪的,但它给了我我需要的数据列表
  • 您在循环的每次迭代中都分配给 同一个字典。将person = {} 移入循环
  • 与整数不同,Python 字典是 可变 对象。也就是说,您可以通过引用他们来更改他们的内容。

标签: python django dictionary for-loop


【解决方案1】:

当您将字典 person 追加到列表 people 时,您只是将字典的引用追加到列表中,因此列表最终只包含对相同的字典。

由于每次循环都会用新值覆盖字典,因此列表最后只包含对您添加的最后一个人的引用。

你需要做的是为每个人创建一个新字典,例如:

for human in humans:
    number_people, people_data = People.data()
    person = dict()
    person['name'] = human.name
    person['age'] = human.age
    person['Sex'] = human.name
    people.append(person)

【讨论】:

  • 从这个非常常见的错误中学到的重要一课是,当您将值分配给字典键时,您会用新值覆盖旧值,但是当您将字典分配给变量时,您只是将变量名重新分配给新的字典对象 - 旧的字典对象仍然存在,并且对它的任何引用仍然有效。
  • 像魅力一样解决了我的问题!我今天学到了一些新东西!
【解决方案2】:

您每次都编辑 same 字典,因此您构造一个新字典,而是编辑旧字典。由于您每次都将 same 字典附加到列表中,因此最终列表包含相同的字典 n 次,并且所有编辑都在该字典上处理。

因此,您必须在 for 循环的每次迭代中构造一个新字典:

people = []
humans = gethumans()

for human in humans:
    number_people, people_data = People.data()
    person = {
        'name': human.name,
        'age': human.age,
        'sex': human.sex
    }
    people.append(person)

我这里用'sex'替换了'Sex'(因为键名不一致很奇怪),并用human.sex代替human.name

这里people.data() 似乎没有做任何事情,因此您可以在此处使用列表推导来生成列表:

people = [
    { 'name': human.name, 'age': human.age, 'sex': human.sex }
    for human in humans
]

这将构建一个包含所有字典的列表。鉴于for 循环没有副作用(看起来就是这种情况),上述方法将起作用。

【讨论】:

  • 顺便说一句:我盯着这个答案看了整整 2 分钟,然后我才决定,是的,“人”这个词 在该代码块中以粗体显示,并且必须看看你是怎么做到的。
  • @AdamSmith:好吧,我从 Prolog 程序员那里得到了这个技巧(如果我没记错的话,垫子)。但我不知道最初是谁开始的:)。
猜你喜欢
  • 2021-12-07
  • 1970-01-01
  • 2018-10-20
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
  • 2018-09-28
  • 2019-10-05
相关资源
最近更新 更多