Pythonでは、clear()
の呼び出しと{}
の辞書への割り当てに違いはありますか?はいの場合、それは何ですか?例:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
同じ辞書も参照している別の変数がある場合、大きな違いがあります。
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}
これは、d = {}
を割り当てると、新しい空の辞書が作成され、d
変数に割り当てられるためです。これにより、d2
は、アイテムがまだ残っている古い辞書を指しています。ただし、d.clear()
は、d
とd2
の両方が指す同じ辞書をクリアします。
d = {}
はd
の新しいインスタンスを作成しますが、他のすべての参照は引き続き古いコンテンツを指します。 d.clear()
は内容をリセットしますが、同じインスタンスへのすべての参照は依然として正しいです。
他の回答で言及された違いに加えて、速度の違いもあります。 d = {}は2倍以上高速です。
python -m timeit -s "d = {}" "for i in xrange(500000): d.clear()"
10 loops, best of 3: 127 msec per loop
python -m timeit -s "d = {}" "for i in xrange(500000): d = {}"
10 loops, best of 3: 53.6 msec per loop
@odanoの答えに加えて、辞書を何度もクリアしたい場合は、d.clear()
を使用する方が速いようです。
import timeit
p1 = '''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d = {}
for i in xrange(1000):
d[i] = i * i
'''
p2 = '''
d = {}
for i in xrange(1000):
d[i] = i * i
for j in xrange(100):
d.clear()
for i in xrange(1000):
d[i] = i * i
'''
print timeit.timeit(p1, number=1000)
print timeit.timeit(p2, number=1000)
結果は次のとおりです。
20.0367929935
19.6444659233
Mutatingメソッドは、元のオブジェクトがスコープ内にない場合に常に役立ちます。
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
辞書を再割り当てすると、新しいオブジェクトが作成され、元のオブジェクトは変更されません。
すでに前述したことの例として:
>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L
言及されていないことの1つは、スコープの問題です。良い例ではありませんが、私が問題に遭遇した場合は次のとおりです。
def conf_decorator(dec):
"""Enables behavior like this:
@threaded
def f(): ...
or
@threaded(thread=KThread)
def f(): ...
(assuming threaded is wrapped with this function.)
Sends any accumulated kwargs to threaded.
"""
c_kwargs = {}
@wraps(dec)
def wrapped(f=None, **kwargs):
if f:
r = dec(f, **c_kwargs)
c_kwargs = {}
return r
else:
c_kwargs.update(kwargs) #<- UnboundLocalError: local variable 'c_kwargs' referenced before assignment
return wrapped
return wrapped
解決策は、c_kwargs = {}
をc_kwargs.clear()
に置き換えることです
誰かがより実用的な例を考えているなら、この投稿を自由に編集してください。
また、dictインスタンスはdictのサブクラスである場合があります(たとえば、defaultdict
)。その場合は、clear
を使用することをお勧めします。これは、dictの正確なタイプを覚える必要がなく、重複コード(クリアラインと初期化ラインを結合する)も避ける必要があるためです。
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)