سؤال

لذلك دعونا نقول اريد ان يكون القاموس. ونحن سوف يطلق عليه d. ولكن هناك طرق متعددة لتهيئة القاموس في بيثون! على سبيل المثال، يمكن أن أفعل هذا:

d = {'hash': 'bang', 'slash': 'dot'}

وأو أنني يمكن أن تفعل هذا:

d = dict(hash='bang', slash='dot')

وأو هذا، بفضول:

d = dict({'hash': 'bang', 'slash': 'dot'})

وأو هذا:

d = dict([['hash', 'bang'], ['slash', 'dot']])

وعلى الآخرين الجمع كله من الطرق مع وظيفة dict(). ومن الواضح أن ذلك واحد من الأشياء dict() تقدم هو المرونة في بناء الجملة والتهيئة. ولكن هذا ليس ما أنا أسأل عنه.

ويقول لي أن جعل d مجرد القاموس فارغة. ما يدور وراء الكواليس من مترجم Python عندما لا d = {} مقابل d = dict()؟ هو ببساطة طريقتان لفعل نفس الشيء؟ هل استخدام {} لديك <ط> إضافية نداء dict()؟ هل لديك واحدة (حتى يكاد يذكر) الحمل أكثر من الآخر؟ في حين أن السؤال هو حقا غير مهم تماما، انها الفضول أحب أن أجبت.

هل كانت مفيدة؟

المحلول

>>> def f():
...     return {'a' : 1, 'b' : 2}
... 
>>> def g():
...     return dict(a=1, b=2)
... 
>>> g()
{'a': 1, 'b': 2}
>>> f()
{'a': 1, 'b': 2}
>>> import dis
>>> dis.dis(f)
  2           0 BUILD_MAP                0
              3 DUP_TOP             
              4 LOAD_CONST               1 ('a')
              7 LOAD_CONST               2 (1)
             10 ROT_THREE           
             11 STORE_SUBSCR        
             12 DUP_TOP             
             13 LOAD_CONST               3 ('b')
             16 LOAD_CONST               4 (2)
             19 ROT_THREE           
             20 STORE_SUBSCR        
             21 RETURN_VALUE        
>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('a')
              6 LOAD_CONST               2 (1)
              9 LOAD_CONST               3 ('b')
             12 LOAD_CONST               4 (2)
             15 CALL_FUNCTION          512
             18 RETURN_VALUE        

وديكت () على ما يبدو بعض C مدمج. الشخص حقا الذكية أو مخصص (ليس لي) يمكن أن ننظر إلى مصدر مترجم واقول لكم المزيد. أردت فقط لاظهار dis.dis. :)

نصائح أخرى

وكما بقدر يذهب الأداء:

>>> from timeit import timeit
>>> timeit("a = {'a': 1, 'b': 2}")
0.424...
>>> timeit("a = dict(a = 1, b = 2)")
0.889...

وJacob: هناك اختلاف في كيفية تخصيص الكائنات، ولكنها ليست نسخ عند الكتابة. بيثون يخصص ذات حجم ثابت "قائمة حرة" حيث يمكن تخصيص بسرعة الأجسام القاموس (حتى يملأ). القواميس المخصصة عن طريق بناء الجملة {} (أو مكالمة C إلى PyDict_New) يمكن أن تأتي من هذه القائمة الحرة. عندما لم تعد تتم الإشارة القاموس يحصل عاد إلى قائمة حرة وأن كتلة الذاكرة يمكن إعادة استخدامها (على الرغم يتم إعادة تعيين حقول الأول).

وهذا القاموس الأول يحصل عاد فورا الى القائمة الحرة، وفي اليوم التالي سوف إعادة استخدام مساحة الذاكرة:

>>> id({})
340160
>>> id({1: 2})
340160

إذا واصلتم إشارة، فإن القاموس المقبل يأتي من فتحة المجانية التالية:

>>> x = {}
>>> id(x)
340160
>>> id({})
340016

ولكن يمكننا حذف الإشارة إلى أن القاموس وتحرير فتحتها مرة أخرى:

>>> del x
>>> id({})
340160

ومنذ يتم التعامل مع بناء الجملة {} في رمز بايت فإنه يمكن استخدام هذا التحسين المذكورة أعلاه. من ناحية أخرى يتم التعامل مع dict() مثل منشئ الفئة العادية ويستخدم بيثون مخصص الذاكرة عام، والتي لا تتبع نمطا يمكن التنبؤ به بسهولة مثل القائمة الحرة أعلاه.

وأيضا، والنظر في compile.c من بيثون 2.6، مع بناء الجملة {} يبدو إلى ما قبل حجم جدول هاش بناء على عدد من البنود انها تخزين والذي يعرف في وقت تحليل.

وأساسا، {} هو جملة والتعامل معها على مستوى اللغة وبايت كود. ديكت () هي فقط المضمن آخر مع جملة التهيئة أكثر مرونة. لاحظ أن ديكت () وأضيف فقط في وسط سلسلة الإصدار 2.x.

تحديث : شكرا على الردود. إزالة التكهنات حول النسخ عند الكتابة.

واحدة الفارق الآخر بين {} وdict هو أن dict يخصص دائما القاموس الجديد (حتى لو كانت المحتويات الثابتة) في حين لا {} <م> دائما القيام بذلك (انظر <لأ href = "HTTPS: //stackoverflow.com/questions/664118/whats-the-difference-between-dict-and/681358#681358">mgood's الإجابة للحصول على متى ولماذا):

def dict1():
    return {'a':'b'}

def dict2():
    return dict(a='b')

print id(dict1()), id(dict1())
print id(dict2()), id(dict2())

وتنتج:

$ ./mumble.py
11642752 11642752
11867168 11867456

وأنا لا أقترح عليك محاولة للاستفادة من هذا أم لا، فإنه يعتمد على حالة معينة، فقط لافتا من ذلك. (كما انها ربما يتضح ذلك من التفكيك إذا فهم أكواد العمليات).

ويستخدم ديكت () عندما تريد إنشاء قاموس من iterable، مثل:

dict( generator which yields (key,value) pairs )
dict( list of (key,value) pairs )
<ع> استخدام مضحك:

def func(**kwargs):
      for e in kwargs:
        print(e)
    a = 'I want to be printed'
    kwargs={a:True}
    func(**kwargs)
    a = 'I dont want to be printed'
    kwargs=dict(a=True)
    func(**kwargs)

والإخراج:

I want to be printed
a

في أجل إنشاء مجموعة فارغة يتعين علينا أن نستخدم مجموعة الكلمة قبل أن أي بمعنى set() هذا يخلق مجموعة فارغة حيث كما هو الحال في dicts فقط الأقواس زهرة يمكن إنشاء ديكت فارغ

ويتيح الذهاب مع مثال

print isinstance({},dict) 
True 
print isinstance({},set) 
False 
print isinstance(set(),set) 
True
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top