我需要创建一个字典,其中键是字符串,值是列表。诀窍是我需要在循环中完成它。
我的最小化代码目前看起来像这样:
for elem in xmlTree.iter():
# skipping root element
if elem.tag == xmlTree.getroot().tag:
continue
# this is supposed to be my temporary list
tmpList = []
for child in elem:
tableWColumns[elem.tag] = tmpList.append(child.tag)
print(tableWColumns)
这仅打印在上一次迭代中创建的列表。
问题显然在于每当我更改列表时,它的所有引用都会被更改。我用Google搜索了那个。我没有用Google搜索的是我在使用循环时如何处理它。
当我想保留列表时,我应该使用的解决方案是将其复制到其他列表,然后我可以更改原始列表而不会丢失数据。我不知道的是,当我基本上需要动态地执行此操作时,我该怎么做。
此外,我仅限于使用标准库。
答案 0 :(得分:3)
问题在于你是在每次迭代中创建tmpList = []
列表并将其放在[]
。所以python在每次迭代中用new替换new,因此你看到最后的迭代结果你的清单。
相反,您可以使用collections.defaultdict
:
from collections import defaultdict
d=defaultdict(list)
for elem in xmlTree.iter():
# skipping root element
if elem.tag == xmlTree.getroot().tag:
continue
# this is supposed to be my temporary list
for child in elem:
d[elem.tag].append(child.tag)
print(tableWColumns)
或者您可以使用dict.setdefault
方法:
d={}
for elem in xmlTree.iter():
# skipping root element
if elem.tag == xmlTree.getroot().tag:
continue
# this is supposed to be my temporary list
for child in elem:
d.setdefault(elem.tag,[]).append(child.tag)
print(tableWColumns)
另请注意,@ abarnert说tmpList.append(child.tag)
将返回None
。因此,在分配后,实际上python会将None
分配给tableWColumns[elem.tag]
。
答案 1 :(得分:1)
这里的一个大问题是tmpList.append(child.tag)
会返回None
。实际上,Python中的几乎所有变异方法都返回None
。
要解决此问题,您可以执行突变,然后将值插入单独的语句中:
for child in elem:
tmpList.append(child.tag)
tableWColumns[elem.tag] = tmpList
...或者不首先尝试改变列表。例如
tableWColumns[elem.tag] = tmpList + [child.tag for child in elem]
这将消除你的所有价值观 - None
问题,但随后你又遇到了新问题。如果任何标签出现不止一次,您只会从该标签的最后一个副本中获取子项,而不是从所有副本中获取。这是因为您每次都会构建一个新列表,并将tableWColumns[elem.tag]
重新分配给该新列表,而不是修改其中的任何内容。
要解决该问题,您需要将现有值提取到tmpList
而不是创建新值:
tmpList = tableWColumns.get(elem.tag, [])
tableWColumns[elem.tag] = tmpList + [child.tag for child in elem]
或者,正如Kasra's answer所述,您可以使用defaultdict
或setdefault
方法来简化此操作。