3

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

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())

无论有无“不”,我都可以将“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

它的行为符合预期。

4

1 回答 1

1

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

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

无论如何,快乐的记录,当您查明失败的比较时,请向我们发布记录器输出。追踪这类“存在的”错误很重要,因为它们揭示了您的假设链或调试方法中的一些损坏或盲点。你就是这样学习的。

于 2018-04-19T05:28:31.447 回答