检查 Python 字典中的所有值时,意外结果为"无"



让我们考虑以下三个词典:

topByClass = {'Real Estate': 'VNO', 'Construction': 'TOL', 'Utilities': 'EXC'}
shouldPass = {'Real Estate': None, 'Construction': None, 'Utilities': 'EXC'}
shouldFail = {'Real Estate': None, 'Construction': None, 'Utilities': None}

我希望将字典中所有值均为 None 的实例与其他所有内容分开。(即前两个应该通过,而最后一个应该失败)

我在网上环顾四周,尤其是像这样的帖子。我在 python 控制台中测试了各种解决方案(在我的 Mac 上的 virtualenv 中运行 Python 2.7),结果如下:

not all(value == None for value in topByClass.values())

无论有没有"not",我都可以将像"topByClass"这样的词典与"shouldFail"分开。

>>> not all(value == None for value in shouldFail.values())
>>> False
>>> not all(value == None for value in topByClass.values())
>>> True

(反之亦然)

问题是,当我去运行 python 文件时,if 语句的计算结果总是好像每个值都是 None。我已经检查了是否可能弄错了字典,但是我在控制台中打印了字典"topByClass",并直接将其粘贴到上面。知道这可能是什么吗?

编辑:

def _getTopByClass(self, assetClass):
# Find the instrument with the highest rank.
ret = None
highestRank = None
for instrument in self.__instrumentsByClass[assetClass]:
rank = self._getRank(instrument)
if rank is not None and (highestRank is None or rank > highestRank):
highestRank = rank
ret = instrument
return ret
def _getTop(self):
ret = {}
for assetClass in self.__instrumentsByClass:
ret[assetClass] = self._getTopByClass(assetClass)
return ret
def _rebalance(self):
topByClass = self.getTop()
self.info(topByClass) # where I get the output I presented above
if any(value is not None for value in topByClass.values()):
self.info("Not All Empty")
else:
self.info("All None")

现在有了上面的"如果",所有人都在打印("不是全部为空")

如果你想看到getRank()或更多,我会推荐PyAlgoTrade的这个例子,因为影响问题的核心机制是相似的。

编辑 2: 以为我可能会提到这一点,以防有人试图复制上面链接的文件......PyAlgoTrade用于下载提要的模块不起作用。因此,您必须使用此软件包来下载数据,以及从csv添加柱线:

feed = yahoofeed.Feed()
feed.addBarsFromCSV("SPY", "data/SPY.csv")
for industry, stocks in instrumentsByClass.items():
for stock in stocks:
feed.addBarsFromCSV(stock, "data/"+stock+".csv")

编辑 3:添加了一些调试信息:

self.info(isinstance(topByClass, dict))
self.info(isinstance(topByClass.values(), list))
self.info(isinstance(topByClass.values()[0], str))

返回:

>>> True
>>> True
>>> True (False when the first value is None)

另外,根据评论,我想我会把它扔进去

self.info(list(topByClass.values()))
>>> [None, None, None, None]

最终编辑:非常感谢所有回复的人,以为我会继续发布我想出的内容,以防有人遇到类似的问题...... 首先是识别问题的代码/输出:

self.info(list(shouldFail.values())
>>> [None, None, None]
self.info(list(topByClass.values())
>>>['VNO', 'TOL', 'EXC']
self.info(list(value is not None for value in topByClass.values()))
>>> [True, True, True]
self.info(any(value is not None for value in topByClass.values()))
>>> <generator object <genexpr> at 0x116094dc0>

我不确定为什么它返回一个生成器,然后我意识到它可能使用 numpy 的 any() 函数,正如我贴花的那样:

import numpy as *

将其更改为:

import numpy as np

它的行为符合预期。

由于您还没有向我们展示导致失败的实际代码(我知道这在生产环境中可能是不可能的),这里有一些关于如何在类层次结构中进行调试的哲学,以及一个关于可能导致这种情况的理论:

  • 在测试实例之前,请添加打印或日志记录语句以打印/记录实例的值。然后你可以看到它是否真的具有你认为的价值("当现实与理论发生碰撞时,现实获胜">)。日志记录应该成为您寻找错误的新朋友。不信任你所有的假设(橡皮鸭子)。但是,日志记录比仔细研究大型类层次结构更快、更可靠。
  • 请注意,您的类层次结构中的某个地方可能会意外进行字符串转换(可能来自其他人编写的某个类,或者意外使用strrepr例如在构造函数、setter 或属性中,或者具有 arg 默认= 'None'而不是Noneinit或方法):'None' != None.这种错误是微妙而阴险的。如果你找到了它,你会边笑边哭。

无论如何,祝您日志记录愉快,当您查明失败的比较时,请向我们发布记录器输出。追踪这些"存在主义"错误很重要,因为它们揭示了你的假设链或调试方法中的一些破碎或盲点。这就是你学习的方式。

最新更新