检查 Python 字典中的所有值时的意外结果是 None
Unexpected results when checking all values in a Python dictionary are None
让我们考虑以下三个词典:
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 的实例与其他所有值分开。 (即前两个应该通过,而最后一个应该失败)
我在网上四处张望,尤其是 post,例如 this one。我在 python 控制台(运行ning Python 2.7 在我的 Mac 上的 virtualenv 中测试了各种解决方案,并且以下工作正常:
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。我已经检查了我是否可能误会了字典,但是我在控制台中打印了 dict "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")
现在上面的"if"都在打印("Not All Empty")
如果您想查看 getRank() 或更多,我会推荐 PyAlgoTrade 中的 this 示例,因为影响问题的核心机制是相似的。
编辑 2:
我想我可能会提到这一点,以防有人试图复制上面链接的文件...... PyAlgoTrade 的下载提要模块不起作用。所以你必须使用 this package 下载数据,以及从 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))
returns:
>>> True
>>> True
>>> True (False when the first value is None)
此外,根据评论,我想我会把它扔进去
self.info(list(topByClass.values()))
>>> [None, None, None, None]
最终编辑:
非常感谢所有做出回应的人,他们认为我会继续 post 我发现的内容以防任何人 运行 遇到类似的问题......
首先确定问题的code/output:
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
它的表现符合预期。
由于您没有向我们展示导致失败的实际代码(我知道这在生产环境中可能是不可能的),这里有一些关于如何在 class 层次结构中进行调试的哲学,以及一种关于 可能 导致这种情况的理论:
- 在测试实例之前,将打印或日志记录语句添加到 print/log 实例的值。然后您可以查看它是否真的具有您认为的价值 ("When reality collides with a theory, reality wins")。日志记录应该成为您寻找漏洞的新朋友。不相信你所有的假设(橡皮鸭他们)。但与仔细研究大型 class 层次结构相比,日志记录更快、更可靠。
- 注意 在您的 class 层次结构 的某处可能会发生意外的字符串转换(可能来自 class 其他人写的,或者意外使用
str
或 repr
例如在构造函数中,setter 或 属性,或 init 或带有 arg default [=12= 的方法] 而不是 None
): 'None' != None
。这种错误是微妙而阴险的。如果你找到了,你会哭着笑着。
无论如何,祝您记录愉快,请 post 在您查明失败的比较时将记录器输出告诉我们。追踪这些 'existential' 错误很重要,因为它们揭示了您的假设链或调试方法中的某些破损或盲点。这就是你的学习方式。
让我们考虑以下三个词典:
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 的实例与其他所有值分开。 (即前两个应该通过,而最后一个应该失败)
我在网上四处张望,尤其是 post,例如 this one。我在 python 控制台(运行ning Python 2.7 在我的 Mac 上的 virtualenv 中测试了各种解决方案,并且以下工作正常:
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。我已经检查了我是否可能误会了字典,但是我在控制台中打印了 dict "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")
现在上面的"if"都在打印("Not All Empty")
如果您想查看 getRank() 或更多,我会推荐 PyAlgoTrade 中的 this 示例,因为影响问题的核心机制是相似的。
编辑 2: 我想我可能会提到这一点,以防有人试图复制上面链接的文件...... PyAlgoTrade 的下载提要模块不起作用。所以你必须使用 this package 下载数据,以及从 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))
returns:
>>> True
>>> True
>>> True (False when the first value is None)
此外,根据评论,我想我会把它扔进去
self.info(list(topByClass.values()))
>>> [None, None, None, None]
最终编辑: 非常感谢所有做出回应的人,他们认为我会继续 post 我发现的内容以防任何人 运行 遇到类似的问题...... 首先确定问题的code/output:
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
它的表现符合预期。
由于您没有向我们展示导致失败的实际代码(我知道这在生产环境中可能是不可能的),这里有一些关于如何在 class 层次结构中进行调试的哲学,以及一种关于 可能 导致这种情况的理论:
- 在测试实例之前,将打印或日志记录语句添加到 print/log 实例的值。然后您可以查看它是否真的具有您认为的价值 ("When reality collides with a theory, reality wins")。日志记录应该成为您寻找漏洞的新朋友。不相信你所有的假设(橡皮鸭他们)。但与仔细研究大型 class 层次结构相比,日志记录更快、更可靠。
- 注意 在您的 class 层次结构 的某处可能会发生意外的字符串转换(可能来自 class 其他人写的,或者意外使用
str
或repr
例如在构造函数中,setter 或 属性,或 init 或带有 arg default [=12= 的方法] 而不是None
):'None' != None
。这种错误是微妙而阴险的。如果你找到了,你会哭着笑着。
无论如何,祝您记录愉快,请 post 在您查明失败的比较时将记录器输出告诉我们。追踪这些 'existential' 错误很重要,因为它们揭示了您的假设链或调试方法中的某些破损或盲点。这就是你的学习方式。