পাইকন-এ ডিক্টর ক্লিয়ার () এবং) assign নির্ধারণের মধ্যে পার্থক্য


167

পাইথনে, ডিকোশনারীকে কল করা clear()এবং বরাদ্দ {}দেওয়ার মধ্যে কি পার্থক্য রয়েছে ? যদি হ্যাঁ, এটি কি? উদাহরণ:

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


আমি অবাক হয়েছি যে এটি আবর্জনা সংগ্রহের অংশে কোনও পার্থক্য করে। আমি মনে করি। ক্লিয়ার () মেমোরি সিস্টেমের কাছে খুব ভাল হওয়া উচিত।
জাভিয়ার নিকোললেট

উত্তর:


285

আপনার যদি অন্য একটি পরিবর্তনশীলও একই অভিধানের উল্লেখ করে থাকে তবে একটি বড় পার্থক্য রয়েছে:

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

এটি কারণ অ্যাসাইনিং d = {}একটি নতুন, খালি অভিধান তৈরি করে এবং এটিকে dভেরিয়েবলের জন্য বরাদ্দ করে । এটি d2এখনও পুরানো অভিধানে আইটেমগুলি সহ নির্দেশ করে leaves যাইহোক, d.clear()একই অভিধান dএবং যে d2উভয় বিন্দু সাফ করে ।


7
ধন্যবাদ। এইবার বুঝতে পারছি. আমাকে এখনও সেই মানসিকতায় অভ্যস্ত হতে হবে যে = অজগরে রেফারেন্স তৈরি করে ...
মার্সিন

15
= কপির নাম উল্লেখ। পাইথনে কোনও ভেরিয়েবল নেই, কেবলমাত্র বস্তু এবং নাম।
tzot

17
আপনার "কোনও ভেরিয়েবলগুলি" বিবৃতিটি প্যাডেন্টিকভাবে সত্য হলেও এটি এখানে সত্যিই সহায়ক নয়। : দীর্ঘ হিসাবে পাইথন ভাষা ডকুমেন্টেশন এখনও "ভেরিয়েবল" সম্পর্কে আলোচনা হিসেবে আমি এখনো শব্দটি ব্যবহার করা যাচ্ছে না docs.python.org/reference/datamodel.html
গ্রেগ Hewgill

9
নাম, ভেরিয়েবল এবং কপির প্রকারগুলি সম্পর্কে আমার চিন্তাভাবনা সামঞ্জস্য করতে আমি জোটের মন্তব্যটি সহায়ক বলে মনে করেছি। এটিকে পেডেন্টিক বলা আপনার মতামত হতে পারে তবে আমি এটি একটি অন্যায়ভাবে কঠোর রায় বলে মনে করি।
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 = {} (?) এর সাথে যুক্ত করতে পারে
রাফ

3
@ রাফা: আমি মনে করি যে বক্তব্যটি হ'ল যদি আমরা জানি যে অন্য কোনও ভেরিয়েবল অভিধান d এর দিকে ইঙ্গিত করছে না, তবে সেটিংটি d = {}দ্রুত হওয়া উচিত কারণ পুরো পরিষ্কার করার পরে আবর্জনা সংগ্রাহকের কাছে রেখে দেওয়া যেতে পারে।
ভাইফায়

8

ইতিমধ্যে আগে উল্লিখিত জিনিসগুলির উদাহরণ হিসাবে:

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

এটি দেখায় যে .clearবস্তুটি সংশোধন করে তবে `= {} a একটি নতুন অবজেক্ট তৈরি করে।
wizzwizz4

7

@ ওডানো'র উত্তর ছাড়াও, আপনি যদি বহুবার ডিকটি 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

একটি বিষয় উল্লেখ করা হয়নি তা হ'ল স্কোপিং ইস্যু। একটি দুর্দান্ত উদাহরণ নয়, তবে আমি এখানে সমস্যাটি নিয়ে এসেছি:

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
@ ফ্যান্টাবোলাস ব্যবহার globalকরে ফাংশনটি অন্যরকমভাবে আচরণ করতে সক্ষম করবে - কনফ_ডেকোরেটরকে সমস্ত কলগুলি একই সি_কওয়ার্গগুলি পরিবর্তনশীল ভাগ করবে। আমি বিশ্বাস করি পাইথন 3 nonlocalএই সমস্যাটি সমাধান করার জন্য কীওয়ার্ড যুক্ত করেছে এবং এটি কার্যকর হবে।
পঙ্কডুডল

1

তদাতিরিক্ত, কখনও কখনও ডিক উদাহরণটি ডিকের একটি সাবক্লাস হতে পারে ( defaultdictউদাহরণস্বরূপ)। clearসেক্ষেত্রে ব্যবহারকে অগ্রাধিকার দেওয়া হয়েছে, কারণ আমাদের ডিকের সঠিক ধরণটি মনে রাখতে হবে না এবং সদৃশ কোডও এড়ানো উচিত নয় (ক্লিয়ারিং লাইনের সাথে ক্লিয়ারিং লাইনের সাথে মিলিত হওয়া)।

x = defaultdict(list)
x[1].append(2)
...
x.clear() # instead of the longer x = defaultdict(list)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.