簡體   English   中英

使用作為列表的鍵從字典中提取值

[英]Extract value from a dictionary using key that is a list

我有以下程序:

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)和“單位”(即周和月)的嵌入列表,並提取正確的值(或比率)。 目前,我在行print deposits([n,unit])遇到錯誤。

這是我得到的錯誤:

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

我的文件名為TestFunction.py

我知道解決這個問題的方法,我將字典轉換為兩個列表,如下所示:

depoMaturities = [ql.Period(1,ql.Weeks), 
                  ql.Period(1,ql.Months),
                  ql.Period(3,ql.Months),
                  ql.Period(6,ql.Months)]

depoRates = [0.0023, 
             0.0032,
             0.0045,
             0.0056]

但它看起來並不那么整潔或復雜。 我真的很感激你的建議。

根據評論更新:看起來Period類不正確地實現了__hash__ ,因此它不遵守Python 所需的散列不變量(特別是,比較相等的對象應該散列到相同的值)。 根據您的評論,當您運行時:

p1 = ql.Period(1,ql.Weeks)
p2 = ql.Period(1,ql.Weeks)
if (p1 == p2): k = 5*2
else: k = 0

你得到 10,所以p1==p2True

當你運行時:

if (hash(p1) == hash(p2)): b = 5*2
else: b = 0

你得到 0,所以hash(p1) == hash(p2)False 這明顯違反了 Python 規則,這使得該類型看起來dict (或set值)的合法鍵,但行為不正確。 基本上,你不能在沒有 QuantLib 的人解決這個問題的情況下使用Period s 作為鍵,或者做一些可怕的事情來解決它(如果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]

如果仍然失敗,那么即使是基本單位類型也已損壞,您根本無法使用它們。


如果鍵是ql.Period s,則需要使用ql.Period s 進行查找(除非Periodtuple子類)。 您還需要使用括號進行dict查找,而不是括號。

如果ql.Periodnamedtuple或類似的,你可以做tuple查找( list s不能是dict鍵,因為它們是可變的):

 for n, unit in [(1,ql.Weeks),(1,ql.Months),(3,ql.Months),(6,ql.Months)]: print deposits[n, unit]

如果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]

存款是一個帶有鍵和值的字典。 字典的參考是

 value = mydict[key]

因此,給定 n 和 unit 你會得到 ql.Period(n, unit) 返回<class 'QuantLib.QuantLib.Period'> 例如, 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

除了其他人已經確定的語法問題之外,我的猜測是您的ql.Period對象不可散列; 字典的鍵需要是可散列的對象。 這是this answer的直接復制和過去,它很好地解釋了這種情況。

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

當你嘗試hash(ql.Period(1,ql.Weeks))時會發生什么? 類似的TypeError 如果您可以控制QuantLib ,您可能會添加一個__hash__方法,以便它們可以在字典中使用。 但是我看到pypi上存在這樣一個模塊,所以我猜你只是在使用它而不是編寫它。

您仍然可以對這些對象進行猴子修補,以給它們一個__hash__方法:

# First define a function to add on as a method
def hash_method(period):
    hash_value = # some code that produces a unique hash, based on
                 # the data contained in the `period` object
    return hash_value

# Now, monkey patch the ql.Period object by giving it this method
ql.Period.__hash__ = hash_method

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM