पाइथन में तानाशाही () और असाइन करना {} के बीच अंतर


167

अजगर में, क्या किसी शब्दकोश में कॉल करने clear()और असाइन {}करने में अंतर है ? यदि हां, तो यह क्या है? उदाहरण:

d = {"stuff":"things"}
d.clear()   #this way
d = {}      #vs this way


मुझे आश्चर्य है कि अगर यह कचरा संग्रह के हिस्से पर फर्क करता है। मुझे लगता है कि .clear () को मेमोरी सिस्टम के लिए अच्छा होना चाहिए।
जेवियर निकोलेट

जवाबों:


285

यदि आपके पास एक और वैरिएबल भी उसी शब्दकोश का जिक्र है, तो एक बड़ा अंतर है:

>>> d = {"stuff": "things"}
>>> d2 = d
>>> d = {}
>>> d2
{'stuff': 'things'}
>>> d = {"stuff": "things"}
>>> d2 = d
>>> d.clear()
>>> d2
{}

ऐसा इसलिए है क्योंकि असाइन करना d = {}एक नया, खाली शब्दकोश बनाता है और इसे dवेरिएबल में असाइन करता है । यह d2अभी भी इसमें मौजूद वस्तुओं के साथ पुराने शब्दकोश की ओर इशारा करता है। हालाँकि, d.clear()एक ही शब्दकोश को साफ करता है कि dऔर d2दोनों बिंदु पर।


7
धन्यवाद। यह समझ में आता है। मुझे अभी भी उस मानसिकता के अभ्यस्त होना है जो = अजगर में संदर्भ बनाता है ...
Marcin

15
= नामों के संदर्भ में प्रतियां। अजगर में कोई चर नहीं हैं, केवल ऑब्जेक्ट और नाम हैं।
tzot

17
हालांकि आपका "नो वेरिएबल्स" कथन पांडित्यपूर्ण रूप से सत्य है, यह वास्तव में यहाँ उपयोगी नहीं है। जब तक पायथन भाषा के दस्तावेज़ अभी भी "चर" के बारे में बात करते हैं, तब भी मैं इस शब्द का उपयोग करने जा रहा हूं: docs.python.org/reference/datamodel.html
ग्रेग

9
मैंने tzot की टिप्पणी को नाम, चर और प्रतियों के बारे में मेरी सोच को समायोजित करने में मददगार पाया। इसे पांडित्य कहना आपकी राय हो सकती है, लेकिन मैं इसे एक कठोर कठोर निर्णय मानता हूं।
cfwschmidt

1
यह भी स्पष्ट () हुक में हटाए गए ऑब्जेक्ट को नष्ट न करें जो अभी भी किसी और द्वारा संदर्भित किया जा सकता है।
लोरेंजो बेल्ली

31

d = {}के लिए एक नया उदाहरण बनाएगा, dलेकिन अन्य सभी संदर्भ अभी भी पुरानी सामग्री को इंगित करेंगे। d.clear()सामग्री को रीसेट करेगा, लेकिन एक ही उदाहरण के सभी संदर्भ अभी भी सही होंगे।


21

अन्य उत्तरों में उल्लिखित अंतरों के अलावा, एक गति अंतर भी है। 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

9
यह वास्तव में सभी मामलों के लिए वैध गति परीक्षण नहीं है क्योंकि तानाशाही खाली है। मुझे लगता है कि एक बड़ा तानाशाह (या कम से कम कुछ सामग्री) बनाने से बहुत छोटा प्रदर्शन अंतर होगा ... साथ ही मुझे संदेह है कि कचरा संग्रहकर्ता अपने स्वयं के चोट के बारे में d = {} (?)
Rafe

3
@ कैफे: मुझे लगता है कि बिंदु यह है कि अगर हम जानते हैं कि कोई अन्य चर डिक्शनरी की ओर इशारा नहीं कर रहा है, तो सेटिंग d = {}तेज होनी चाहिए क्योंकि पूरी सफाई बाद में कचरा कलेक्टर को छोड़ दी जा सकती है।
वीएफएफआई

8

पहले से बताई गई बातों के लिए एक दृष्टांत के रूप में:

>>> a = {1:2}
>>> id(a)
3073677212L
>>> a.clear()
>>> id(a)
3073677212L
>>> a = {}
>>> id(a)
3073675716L

इससे पता चलता है कि .clearवस्तु को संशोधित करता है लेकिन `= {}` एक नई वस्तु बनाता है।
wizzwizz4

7

@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

4
मुझे यकीन नहीं है कि अंतर महत्वपूर्ण है। वैसे भी, मेरी मशीन पर, परिणाम विपरीत हैं!
अरिस्टाइड

7

यदि मूल वस्तु दायरे में नहीं है, तो उत्प्रेरण विधियां हमेशा उपयोगी होती हैं:

def fun(d):
    d.clear()
    d["b"] = 2

d={"a": 2}
fun(d)
d          # {'b': 2}

शब्दकोश को फिर से असाइन करने से एक नई वस्तु बनेगी और मूल को संशोधित नहीं किया जा सकेगा।


4

एक बात का उल्लेख नहीं है मुद्दों scoping है। एक महान उदाहरण नहीं है, लेकिन यहाँ मामला है जहाँ मैं समस्या में भाग गया:

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बहुत अधिक उपयोग करने के लिए सबसे अच्छी बात नहीं है।
काल्पनिक जूल

3
@fantabolous का उपयोग globalकरने से फ़ंक्शन अलग-अलग व्यवहार करेगा - सभी कॉल conf_decorator तब उसी c_kwargs चर को साझा करेंगे। मेरा मानना ​​है कि पायथन 3 ने nonlocalइस मुद्दे को संबोधित करने के लिए कीवर्ड जोड़ा , और यह काम करेगा।
पोंकडूडल

1

इसके अलावा, कभी-कभी तानाशाह का उदाहरण तानाशाही ( defaultdictउदाहरण के लिए) का उपवर्ग हो सकता है । उस मामले में, का उपयोग clearकरना पसंद किया जाता है, क्योंकि हमें सही प्रकार का ताना-बाना याद नहीं रखना है, और डुप्लिकेट कोड से भी बचना चाहिए (शुरुआती लाइन के साथ क्लियरिंग लाइन को युग्मित करना)।

x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.