[英]insert an element into a list of dictionaries
I have declared an empty list and I want to append dictionaries through a for
loop by using the extend()
method, but I end with a list with the same content in all its positions (the same dictionary) 我已经声明了一个空列表,我想通过使用
extend()
方法通过for
循环追加字典,但是我最后得到一个列表,该列表的所有位置都具有相同的内容(相同的字典)
This is the code: 这是代码:
def get_tasks(self, actor, task_state):
tasks = Task.objects.filter(actor=actor.id, state=task_state)
tasks_to_return = []
task_data = {}
for task in tasks:
task_data['name'] = getattr(task, 'name')
task_data['description'] = getattr(task, 'description')
task_data['start_date'] = getattr(task, 'start_date')
task_data['finish_date'] = getattr(task, 'finish_date')
task_data['situation'] = task.get_situation()
tasks_to_return.extend(task_data)
return tasks_to_return
If I change extend()
for append()
, the result is even worst. 如果我将
extend()
更改为append()
,结果将更糟。
That is because you each time add the same dictionary to the list: indeed you only change the key/values of that dictionary, and add that dictionary a second time, etc. 那是因为您每次都将相同的词典添加到列表中:实际上,您只更改了该词典的键/值,然后第二次添加了该词典,依此类推。
Furthermore by using extend
, you actually add a iterable of elements to a list. 此外,通过使用
extend
,您实际上将一个可迭代的元素添加到列表中。 A dictionary is an iterable : you iterate over the keys. 字典是可迭代的 :您遍历键。
So what you should do is (1) construct a new dictionary each time, and (2) use append
instead of extend: 因此,您应该做的是(1)每次构造一个新字典,(2)使用
append
而不是extend:
for task in tasks:
task_data = {}
task_data['name'] = getattr(task, 'name')
task_data['description'] = getattr(task, 'description')
task_data['start_date'] = getattr(task, 'start_date')
task_data['finish_date'] = getattr(task, 'finish_date')
task_data['situation'] = task.get_situation()
tasks_to_return.
append(task_data)
We can also improve the code, for instance instead of setting the key-value pairs, we can do this at the construction of the dictionary. 我们还可以改进代码,例如,代替设置键值对,我们可以在构建字典时做到这一点。 You use
getattr(..)
, but this is not necessary here: we can use task.name
instead of getattr(task, 'name')
, so a more elegant approach is probably: 您可以使用
getattr(..)
,但这不是必需的:我们可以使用task.name
代替getattr(task, 'name')
,因此一种更优雅的方法可能是:
tasks_to_return = []
task_data = {}
for task in tasks:
task_data = { 'name': task.name, 'description': task.description, 'start_date': task.start_date, 'finish_date': task.finish_date, 'situation': task.situation }
tasks_to_return.append(task_data)
Now since the list is initially empty, we can also use list comprehension : 现在,由于列表最初是空的,因此我们还可以使用列表理解 :
tasks_to_return = [ {
'name': task.name,
'description': task.description,
'start_date': task.start_date,
'finish_date': task.finish_date,
'situation': task.situation
}
for task in tasks]
Your extend
or append
adds the original reference to task_data
, whose contents you keep changing. 您的
extend
或append
将原始引用添加到task_data
,您不断更改其内容。 Instead, either make a new empty object for task_data
, or append a copy of the one you reuse: 相反,要么为
task_data
创建一个新的空对象,要么附加一个您要重用的对象的副本:
import copy
...
tasks_to_return.append(copy.copy(task_data))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.