Python 使用作为列表的键从字典中提取值

Python 使用作为列表的键从字典中提取值,python,dictionary,quantlib-swig,Python,Dictionary,Quantlib Swig,我对以下节目有兴趣: import QuantLib as ql deposits = {ql.Period(1,ql.Weeks): 0.0023, ql.Period(1,ql.Months): 0.0032, ql.Period(3,ql.Months): 0.0045, ql.Period(6,ql.Months): 0.0056} for n, unit in [(1,ql.Weeks),(1,ql.Mont

我对以下节目有兴趣:

import QuantLib as ql

deposits = {ql.Period(1,ql.Weeks): 0.0023, 
            ql.Period(1,ql.Months): 0.0032,
            ql.Period(3,ql.Months): 0.0045,
            ql.Period(6,ql.Months): 0.0056}

for n, unit in [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]:
    print deposits([n,unit])
我希望这个程序能做的是:它循环遍历字典键,其中包含一个嵌入的“数字”(即1,1,3,6)和“单位”(即周和月)列表,并提取正确的值(或速率)。目前,我在打印存款([n,单位])行中遇到一个错误。

以下是我得到的错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 699, in runfile
    execfile(filename, namespace)
  File "C:\Anaconda2\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 74, in execfile
    exec(compile(scripttext, filename, 'exec'), glob, loc)
  File "TestFunction.py", line 16, in <module>
    print deposits([n,unit])   
TypeError: 'dict' object is not callable

但这样一来,它看起来就没有那么整洁或复杂了。非常感谢您的建议。

存款是一本包含键和值的字典。词典的参考文献是

 value = mydict[key]
因此,给定n和单位,就得到ql.Period(n,unit)返回一种类型的
。例如,
ql.period(1,ql.Weekly)
的结果将是1W

如果将其转换为字符串,则它可以用作键

deposits = {str(ql.Period(1,ql.Weeks)): 0.0023, 
            str(ql.Period(1,ql.Months)): 0.0032,
            str(ql.Period(3,ql.Months)): 0.0045,
            str(ql.Period(6,ql.Months)): 0.0056}

value = deposits[str(ql.Period(n, unit))]
print value

Updateper:它看起来像是
Period
类执行的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu>不正确,因此它不服从(具体地说,比较相等的对象应该散列到相同的值)。根据您的评论,当您运行时:

p1 = ql.Period(1,ql.Weeks)
p2 = ql.Period(1,ql.Weeks)
if (p1 == p2): k = 5*2
else: k = 0
if (hash(p1) == hash(p2)): b = 5*2
else: b = 0
得到10,因此
p1==p2
True

运行时:

p1 = ql.Period(1,ql.Weeks)
p2 = ql.Period(1,ql.Weeks)
if (p1 == p2): k = 5*2
else: k = 0
if (hash(p1) == hash(p2)): b = 5*2
else: b = 0
得到0,因此
hash(p1)=hash(p2)
False
。这显然违反了Python规则,使类型看起来像是
dict
(或
集合中的值)的合法键,但行为不正确。基本上,如果没有QuantLib的人来解决这个问题,或者没有做一些糟糕的事情来解决这个问题,你就不能使用
Period
作为键(如果
Period
是一个C扩展类型,这似乎很有可能,因为QuantLib显然是一个SWIG包装器)

如果
Period
单位运行正常,我建议在大多数情况下使用成对计数和单位的
tuple
s,并且仅在需要特定
Period
功能时转换为
Period
s。因此,您的
dict
将是:

deposits = {(1,ql.Weeks): 0.0023, 
            (1,ql.Months): 0.0032,
            (3,ql.Months): 0.0045,
            (6,ql.Months): 0.0056}
for n, unit in [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]:
    print deposits[n, unit]
你的循环是:

deposits = {(1,ql.Weeks): 0.0023, 
            (1,ql.Months): 0.0032,
            (3,ql.Months): 0.0045,
            (6,ql.Months): 0.0056}
for n, unit in [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]:
    print deposits[n, unit]
如果仍然失败,那么即使是基本的单元类型也会被破坏,你根本无法使用它们


如果键是
ql.Period
s,则需要使用
ql.Period
s进行查找(除非
Period
tuple
子类)。您还需要在
dict
查找中使用括号,而不是括号

如果
ql.Period
是一个
namedtuple
或类似的,您可以执行
tuple
查找(
list
s不能是
dict
键,因为它们是可变的):

如果
ql.Period
不是
tuple
子类,则可以执行以下操作:

for n, unit in [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]:
    print deposits[ql.Period(n, unit)]
或者循环中的周期

import itertools

for period in itertools.starmap(ql.Period, [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]):
    print deposits[period]

除了其他人发现的语法问题之外,我猜您的
ql.Period
对象是不可散列的;字典的键需要是可散列对象。这是一份直接副本和过去的,很好地解释了这种情况

>>> a = {}
>>> b = ['some', 'list']
>>> hash(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>> a[b] = 'some'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable

你应该编辑你的问题,以包括你得到的准确和完整的错误。作为第一个猜测,错误是你不能调用dict。如果这是你问题中的一个输入错误,那么下一个错误是列表不能散列。如果这不是一个问题,那么最后,您将得到一个KeyError,因为您用作获取打印值的键的对象与您创建字典时使用的对象类型(或值)不同。我已经包含了我得到的错误。鉴于我拥有的字典“存款”,你能告诉我如何提取这些值吗?事实上:dict是不可调用的。这是一个输入错误:使用
[]
,而不是
()
,来访问dict的元素。接下来,如答案所示,您需要根据数量和单位创建一个
ql.Period
对象,因为您的dict有
ql.Period
对象作为键。感谢您的回复。我刚刚运行了您的建议,但得到了错误
打印存款[ql.Period(n,unit)]键错误:Period(“1W”)
@MacMavin打印n和unit,并打印ql.Weeks,以确保两者匹配。还要检查您的代码中是否有句点ql.period(1,'W')中的两个参数的逗号。我已经打印了语句;以下是结果:命令:
printn,unit,ql.Months
results:
12;1 2 2;  3 2 2;  6.2.2我要解释这个结果:在quantlib库中,ql.Months的索引为2,而ql.Weeks的索引为1。产生的结果与预期一致。第一行表示1周、第二个1月、第三个3月和第四个6个月。我不能从print语句中看出任何错误。@MacMavin我没有计算机上可用的QuantLib模块。我将尝试在家里安装它,并在今晚查看它,但我不知道我是否能够得到它。尝试明确查看存款[ql.Period[(1,1)]
并查看其是否有效。如果有效,则验证您键入的存款[n,单位]
是否正确。我尝试了您的建议,但仍然得到一个错误
回溯(最后一次调用):文件“”,文件中的第1行“C:\Anaconda2\lib\site packages\spyderlib\widgets\externalshell\sitecustomize.py”,第699行,在运行文件execfile(文件名,命名空间)文件“C:\Anaconda2\lib\site packages\spyderlib\widgets\externalshell\sitecustomize.py”中,第74行,在execfile exec(compile(scripttext,filename,'exec'),glob,loc)文件“TestFunction.py”中“,第16行,在存款[ql.Period[(1,1)]]TypeError:“type”对象没有属性“\uu getitem\uuuu'>>”
Period是quantlib的类成员函数。在我的例子中,ql.Period接受一个数字(表示时间)及其单位(周、月等)。因此
ql.Period(1,ql.weeks)
将产生“1W”.从您的回复中,我推测您可能没有遇到quantlib。很抱歉,我没有更清楚地描述quantlib部分。在实施您的建议后,我仍然会遇到错误