以特定键值开始循环字典

5 python performance dictionary for-loop python-2.7

这是代码:

编辑****请不要再"无法使用无序字典回复".我几乎已经知道了.我发布了这篇文章的可能性很大,或者有人有可行的想法.

#position equals some set of two dimensional coords
for name in self.regions["regions"]:  # I want to start the iteration with 'last_region'
    # I don't want to run these next two lines over every dictionary key each time since the likelihood is that the new
    # position is still within the last region that was matched.
    rect = (self.regions["regions"][name]["pos1"], self.regions["regions"][name]["pos2"])
    if all(self.point_inside(rect, position)):
        # record the name of this region in variable- 'last_region' so I can start with it on the next search...
        # other code I want to run when I get a match
        return
return # if code gets here, the points were not inside any of the named regions
Run Code Online (Sandbox Code Playgroud)

希望代码中的注释能够很好地解释我的情况.让我说我最后在区域"delta"(即,键名称为delta,值将是定义它的边界的坐标集),我还有500个区域.我第一次发现自己处于区域delta时,代码可能没有发现这个,直到(假设),第389次迭代......所以它all(self.point_inside(rect, position))在发现之前进行了388次计算.因为下次运行时我可能仍会处于增量状态(但我必须在每次代码运行时验证它),如果密钥"delta"是第一个被for循环检查的那个,那将会很有帮助.

这个特定的代码可以为许多不同的用户每秒运行多次..因此速度至关重要.设计很常见,用户不会在一个区域内,并且所有500条记录可能需要循环通过并且将在没有匹配的情况下退出循环,但我希望通过加快速度来加快整个程序的速度.那些目前在其中一个地区的人.

我不希望以任何特定的顺序对字典进行排序等额外的开销.我只是希望它开始寻找它成功匹配的最后一个字典 all(self.point_inside(rect, position))

也许这会有所帮助..以下是我使用的字典(只显示了第一条记录),所以你可以看到我编码到上面的结构......是的,尽管代码中的名称是"rect",它实际上会检查立方体区域中的点.

{"regions":{"shop":{"flgs":{"breakprot":true,"placeprot":true},"dim":0,"placeplayers":{"4f953255-6775-4dc6-a612-fb4230588eff ":"SurestTexas00"},"breakplayers":{"4f953255-6775-4dc6-a612-fb4230588eff":"SurestTexas00"},"protected":true,"banplayers":{},"pos1":[5120025,60 ,5120208],"pos2":[5120062,73,5120257],"ownerUuid":"4f953255-6775-4dc6-a612-fb4230588eff","accessplayers":{"4f953255-6775-4dc6-a612-fb4230588eff":" SurestTexas00"}},更多,更多,更多...}

por*_*ros 2

您可以尝试在 的自定义子类中实现一些缓存机制dict

您可以设置一个self._cache = Nonein __init__,添加一个方法,例如set_cache(self, key)设置缓存,最后在调用默认值之前覆盖__iter__to 。yield self._cache__iter__

然而,如果你考虑这个 stackoverflow 答案这个答案,这可能有点麻烦。

对于您的问题中所写的内容,我会尝试在您的代码中实现此缓存逻辑。

def _match_region(self, name, position):
    rect = (self.regions["regions"][name]["pos1"], self.regions["regions"][name]["pos2"])
    return all(self.point_inside(rect, position))


if self.last_region and self._match_region(self.last_region, position):
    self.code_to_run_when_match(position)
    return

for name in self.regions["regions"]:
    if self._match_region(name, position):
        self.last_region = name
        self.code_to_run_when_match(position)
        return
return # if code gets here, the points were not inside any of the named regions
Run Code Online (Sandbox Code Playgroud)