-1

次のプログラムがあります。

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

私はこの問題を回避する方法を知っています。これは、次のように辞書を 2 つのリストに変換する場所です。

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]

しかし、それはきちんとしたものでも洗練されたものでもありません。アドバイスをいただければ幸いです。

4

3 に答える 3

1

コメントごとに更新:Periodクラスが正しく実装されていないように見えるため、Python で必要なハッシュ不変__hash__条件に従わない(具体的には、等しいと比較されるオブジェクトは同じ値にハッシュする必要があります)。あなたのコメントによると、実行すると:

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

あなたは10を得る、そうp1==p2ですTrue

実行すると:

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

あなたは0を得る、そうhash(p1) == hash(p2)ですFalse。これは明らかに Python の規則に違反しており、型が a (または a の値)の有効なキーのように見えますが、正しく動作しません。基本的に、QuantLib の人々にこれを修正してもらうか、それを回避するためにひどいことをしない限り、 s をキーとして使用することはできません( QuantLib が明らかに SWIG ラッパーであるため、C 拡張タイプの場合は本当にひどいことです)。dictsetPeriodPeriod

Period単位が適切に動作する場合は、tupleほとんどの場合、ペアになったカウントと単位のs を使用Periodし、特定の機能が必要な場合にのみ s に変換することをお勧めしますPeriod。だからあなたは次の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.Periods の場合、s を使用して検索する必要があります(がサブクラスでql.Periodない場合)。また、括弧ではなく、ルックアップに括弧を使用する必要があります。Periodtupledict

ql.Periodが anamedtupleなどの場合は、tupleルックアップを実行できます ( listsdictは変更可能であるため、キーにすることはできません)。

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]

于 2016-03-07T17:30:08.273 に答える
0

預金は、キーと値を持つディクショナリです。辞書の参照は

 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
于 2016-03-07T17:26:36.847 に答える
0

他の人が特定した構文の問題に加えて、私の推測では、あなたの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

しようとするとどうなります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
于 2016-03-07T19:07:34.627 に答える