ในหลามมีความแตกต่างระหว่างการโทรclear()
และการกำหนดให้{}
กับพจนานุกรมหรือไม่ ถ้าใช่มันคืออะไร ตัวอย่าง:
d = {"stuff":"things"}
d.clear() #this way
d = {} #vs this way
ในหลามมีความแตกต่างระหว่างการโทร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 = {} เร็วกว่าสองเท่า:
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
d = {}
ควรเร็วขึ้นเนื่องจากการล้างข้อมูลทั้งหมดสามารถทิ้งไว้ที่ Garbage Collector ได้ในภายหลัง
ในฐานะที่เป็นภาพประกอบสำหรับสิ่งที่กล่าวถึงก่อนหน้านี้:
>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L
.clear
ปรับเปลี่ยนวัตถุ แต่ `= {} 'สร้างวัตถุใหม่
นอกเหนือจากคำตอบของ @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
วิธีการกลายพันธุ์จะมีประโยชน์เสมอหากวัตถุต้นฉบับไม่อยู่ในขอบเขต:
def fun(d):
d.clear()
d["b"] = 2
d={"a": 2}
fun(d)
d # {'b': 2}
การกำหนดพจนานุกรมใหม่จะสร้างวัตถุใหม่และจะไม่แก้ไขต้นฉบับ
สิ่งหนึ่งที่ไม่ได้กล่าวถึงคือการกำหนดขอบเขต ไม่ใช่ตัวอย่างที่ดี แต่นี่เป็นกรณีที่ฉันพบปัญหา:
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()
หากใครบางคนคิดตัวอย่างที่เป็นประโยชน์ได้มากขึ้นอย่าลังเลที่จะแก้ไขโพสต์นี้
global c_kwargs
อาจจะไม่ทำงานหรือไม่ แม้ว่าอาจglobal
ไม่ใช่สิ่งที่ดีที่สุดที่จะใช้บ่อยๆ
global
จะทำให้ฟังก์ชั่นทำงานแตกต่างกัน - การเรียกไปที่ conf_decorator ทั้งหมดจะแบ่งปันตัวแปร c_kwargs เดียวกัน ฉันเชื่อว่า Python 3 เพิ่มnonlocal
คำหลักเพื่อแก้ไขปัญหานี้และสิ่งนี้จะใช้ได้
นอกจากนี้บางครั้งอินสแตนซ์ dict อาจเป็นคลาสย่อยของ dict ( defaultdict
ตัวอย่าง) ในกรณีดังกล่าวclear
เราแนะนำให้ใช้เพราะเราไม่จำเป็นต้องจำชนิด dict ที่แน่นอนและยังหลีกเลี่ยงรหัสที่ซ้ำกัน
x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)