在循环中生成列表字典(3.2.3)

2024-09-30 22:10:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要创建一个字典,其中键是字符串,值是列表。诀窍是我需要做一个循环。你知道吗

目前,我的简化代码如下所示:

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上搜索到使用循环时如何处理它的方法。你知道吗

当我想保留列表时,我应该使用的解决方案是将它复制到其他列表中,然后我可以在不丢失数据的情况下更改原始列表。我不知道的是我该怎么做,当我基本上需要动态地做这个的时候。你知道吗

此外,我仅限于使用标准库。你知道吗


Tags: 字符串代码inchild列表for字典tag
2条回答

问题是因为您在每个迭代中创建tmpList = []列表并将其放入[],所以python在每个迭代中将新的替换为旧的,这样您就可以在列表中看到最后一个迭代结果。你知道吗

相反,您可以使用^{}

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)

或者可以使用^{}方法:

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]。你知道吗

这里最大的问题是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所说,您可以通过使用defaultdictsetdefault方法来简化这个过程。你知道吗

相关问题 更多 >