2011-01-04 9 views
3

デフォルト値を返すには、Pythonの辞書アクセス機構 "getitem"を書き直したいと思います。デフォルト値を得るためにpython dictsを書き換える方法

私が探しています機能は

a = dict() 
a.setdefault_value(None) 
print a[100] #this would return none 

任意のヒントのようなものでしょうか?すでにcollections.defaultdictあり

おかげ

+1

別の可能性は 'a.get(100、なし)を使用することです' – UncleZeiv

+0

はい、私はその1つのおかげで知っています。しかし、それは私のコード全体にあることはちょっと醜いです。 – webDevelSouth

+0

欠落しているキーをNoneに設定するか、KeyErrorを発生させる代わりにNoneを返すだけですか? – kevpie

答えて

11

from collections import defaultdict 

a = defaultdict(lambda:None) 
print a[100] 
+0

あなたのラムダは 'lambda:None'でなければなりません。そうでなければ' TypeError:()は正確に1つの引数(与えられた0) 'をとります。 –

+0

@bukzor、Steven:そうです、あなたが入力している間に私はおそらくそれを修正しました。 –

3

は、Python 2.6で始まるdefaultdict built-inがあります。コンストラクタは、値が見つからない場合に呼び出される関数を取ります。これは単にNoneを返すよりも柔軟性があります。

from collections import defaultdict 

a = defaultdict(lambda: None) 
print a[100] #gives None 

lambdaは、名前のない1行の関数を定義するだけの簡単な方法です。このコードは等価です:

def nonegetter(): 
    return None 

a = defaultdict(nonegetter) 
print a[100] #gives None 

これは、一意の各オブジェクトの数を示すハッシュを与える非常に便利なパターンです。通常のdictを使用すると、KeyErrorを回避する特別なケースが必要になります。

counts = defaultdict(int) 
for obj in mylist: 
    counts[obj] += 1 
+0

とどうすればdefaultdictの使用を避けることができますか? – webDevelSouth

+0

@webDevelSouth:なぜdefaultdictの使用を避けたいですか? –

+0

私は彼がこれをpython OOPの足掛かりとして使用していると推測しています。私はこれを別の答えに入れました。 – bukzor

1

使用defaultdictコンストラクタへの引数は、デフォルト値を返す関数であるdefaultdicthttp://docs.python.org/library/collections.html#collections.defaultdict

import collections 
a = collections.defaultdict(lambda:None) 

。あなたが未設定のエントリにアクセスする場合、それが実際にデフォルトに設定すること

注:

>>> print a[100] 
None 
>>> a 
defaultdict(<function <lambda> at 0x38faf0>, {100: None}) 
1

あなた本当にがdefaultdictの組み込みを使用しないようにしたい場合は、辞書の独自のサブクラスを定義する必要があります、そのよう:

class MyDefaultDict(dict): 
    def setdefault_value(self, default): 
     self.__default = default 
    def __getitem__(self, key): 
     try: 
      return self[key] 
     except IndexError: 
      return self.__default 
+0

と私はスクリプトの一番上にdictとしてMyclassDefaultDictをインポートして、 "dict"としてMyclassDefaultDictを行うことができたと思います - 私は正しいですか? – webDevelSouth

+4

まあ、そうかもしれませんが、そうすべきではありません。 1つは、中括弧を使用して定義したディクショナリでは、それが行われません。 '{" foo ":1}'は 'dict'を他のクラスに再定義したとしてもまだPythonの' dict'です。別の場合は、あなたのコードを保持している人(自分自身を含めて6か月間)が 'dict'を見れば、それは通常のPythonのdictタイプと見なされます。 – kindall

0

私はdefaultdictの意識波平、おそらく行くための最善の方法のthats。あなたが何らかの理由で過去にこの目的のために小さなラッパー関数を書かれたことに反対するならば。わずかに異なる機能がありますが、それはあなたにとって良いかもしれません。

def makeDictGet(d, defaultVal): 
    return lambda key: d[key] if key in dict else defaultVal 

そして、それを使用して...

>>> d1 = {'a':1,'b':2} 
>>> d1Get = makeDictGet(d1, 0) 
>>> d1Get('a') 
1 
>>> d1Get(5) 
0 
>>> d1['newAddition'] = 'justAddedThisOne' #changing dict after the fact is fine 
>>> d1Get('newAddition') 
'justAddedThisOne' 
>>> del d1['a'] 
>>> d1Get('a') 
0 
>>> d1GetDefaultNone = makeDictGet(d1, None) #having more than one such function is fine 
>>> print d1GetDefaultNone('notpresent') 
None 
>>> d1Get('notpresent') 
0 
>>> f = makeDictGet({'k1':'val1','pi':3.14,'e':2.718},False) #just put new dict as arg if youre ok with being unable to change it or access directly 
>>> f('e') 
2.718 
>>> f('bad') 
False 
関連する問題