【问题标题】:python dict ends empty after iterationpython dict在迭代后结束为空
【发布时间】:2011-04-15 09:29:42
【问题描述】:

我在 python 中使用 dict 时遇到问题,我最终得到的是空字典。

看起来我每次都删除数据

此代码假设生成一个包含每个站点的测试的测试。

提前致谢

tests={}
for t in Test.objects.all():
    for s in Site.objects.all():
        site={}
        for sv in s.siteversions.all():
            siteversion=sv.version
            results=sv.results.filter(idTest=t)
            result=""
            if(results):
                result=results[0].result_test()
            site.update({sv.version:result})
        tests.update({t.name:site.copy()})
print tests

{u'load stuff': {u'X2': 'Success', u'X1': ''}}
{u'load stuff': {u'XP': 'Error'}}
{u'load stuff': {}}
{u'load stuff': {}, u'unload': {u'X2': 'Fail', u'X1': 'Error'}}
{u'load stuff': {}, u'unload': {u'XP': 'Success'}}
{u'load stuff': {}, u'unload': {}}

x2 和 xp 是版本

【问题讨论】:

  • 似乎应该有一种更简单的方法来做到这一点。看起来你有 Test,Site,SiteVersionResults。您不能使用select_related 迭代“结果”并收集测试名称、站点名称和站点版本吗?
  • 好吧,我需要那种结构来制作表格,但我确实喜欢 select_related。

标签: python django dictionary


【解决方案1】:

您确定您有TestSite 对象,Site 对象有versions,并且每个siteversionversion 属性都有一个值,并且它们都是不同的吗?尝试放入一些打印语句进行调试。

还有,这种事情:

site.update({sv.version:result})

是不必要的笨拙。应该是:

site[sv.version] = result

(与tests 相同)。

【讨论】:

  • 它获取数据,但每次迭代都会删除'dict'中的前一个
【解决方案2】:

tests.update({t.name:site.copy()}) 为每个站点执行,但使用相同的键:testname 和 somtimes you have sites witout test -> 以空字典结束。

要解决此问题,您需要如下结构:

Test1 -> site1 -> test_results1
         site2 -> test_results2
         ...

Test2 -> site1 -> test_results1
         site2 -> test_results2
         ...

类似这样的:

tests={}
for t in Test.objects.all():
    sites={}
    for s in Site.objects.all():
        site_results={}
        for sv in s.siteversions.all():
            results=sv.results.filter(idTest=t)
            result = ''
            if(results):
                result=results[0].result_test()
            site_results[sv.version] = result
    sites[s.name] = site_results
tests[t.name] = sites

print tests

【讨论】:

    【解决方案3】:

    我需要那种结构来制作表格,但我确实喜欢 select_related

    我不认为这是真的。

    我假设你的 models.py 是这样的:

    class Test(models.Model):
      name = models.CharField(unique=True)
    
    class Site(models.Model):
      name = models.CharField(unique=True)
    
    class SiteVersion(models.Model):
      name    = models.CharField()
      site    = models.ForeignKey(Site)
      results = models.ManyToManyField(Test,through='TestResults')
      class Meta:
        unique_together = ((name,site),)
    
    class TestResults(models.Model):
      siteversion = models.ForeignKey(SiteVersion)
      test        = models.ForeignKey(Test)
      class Meta:
        unique_together = ((siteversion,test),)
      def result_test(self):
        # Not sure about this bit, presuming you've got something else on your Test model
        return self.test.XXXX(self.siteversion)
    

    在这种情况下,您应该能够执行以下操作:

    table = {}
    for r in TestResults.objects.select_related('test__name','siteversion__name','siteversion__site__name'):
      table.setdefault(r.test__name,{}).setdefault(r.siteversion__site__name,{})[r.siteversion__name] = r.result_test()
    

    【讨论】: