क्या एक शाब्दिक और एक तानाशाह के निर्माण का उपयोग करने के बीच अंतर है?


204

PyCharm का उपयोग करना, मैं इसे एक कन्वर्ट करने के लिए प्रदान करता है पर ध्यान dict शाब्दिक :

d = {
    'one': '1',
    'two': '2',
}

एक तानाशाह निर्माता में :

d = dict(one='1', two='2')

क्या ये विभिन्न दृष्टिकोण कुछ महत्वपूर्ण तरीके से भिन्न हैं?

(इस प्रश्न को लिखते समय मैंने देखा कि dict()संख्यात्मक कुंजी को निर्दिष्ट करना असंभव लगता है .. d = {1: 'one', 2: 'two'}संभव है, लेकिन, जाहिर है, dict(1='one' ...)कोई और है?)


4
dict()कुंजी-मान वाले युग्मों की एक सूची लेता है और साथ ही नामित मापदंडों की अनुमति देता है, इसलिए इसका उपयोग किसी भी प्रकार का तानाशाही बनाने के लिए किया जा सकता है, बस उस सिंटैक्स के साथ नहीं जिसका आप उपयोग कर रहे हैं। यह भी शायद कुछ भी नहीं लायक है कि pyCharm में एक बग ( youtrack.jetbrains.net/issue/PY-2512 ) था क्योंकि विशेष रूप से आपने जो खोजा था, जो तय हो गया है)।
जुले

1
संबंधित: stackoverflow.com/questions/5790860/… (सारांश: PyCharm का व्यवहार धीमा और बदसूरत है)
Wooble

1
जाहिरा तौर पर CPython 2.7 तानाशाही () धीमी (6 गुना धीमी?) है। देखें: doughellmann.com/2012/11/… किसी भी मामले में मैं कंस्ट्रक्टर सिंटैक्स वैसे भी पसंद करना शुरू कर रहा हूं क्योंकि मुझे डाइक और फ़ंक्शन कॉल के बीच कोड टाइप करना और स्थानांतरित करना आसान लगता है।
डेविड व्हीटन

2
रिक्त स्थान न भूलें: आप वे कुंजियाँ नहीं बना सकते जिनमें दूसरे तरीके का उपयोग करने वाले स्थान हों। पहला तरीका, हालांकि, कोई भी स्ट्रिंग ले सकता है, यह परवाह नहीं करेगा। यही बात यूनिकोड पर भी लागू होती है।
कैमिलबी

2
पायथन 2 में, dict(abc = 123)कंस्ट्रक्टर बाइट-स्ट्रिंग कुंजियों के साथ एक शब्दकोश का निर्माण करता है 'abc', जो कि यदि आप उपयोग कर रहे हैं unicode_literalsऔर यूनिकोड होने के लिए शब्दकोश कुंजियों की अपेक्षा कर रहे हैं तो आश्चर्य हो सकता है u'abc'Stackoverflow.com/questions/20357210/… देखें ।
ली-आंग येप

जवाबों:


116

मुझे लगता है कि आपने सबसे स्पष्ट अंतर बताया है। इसके अलावा,

पहले देखने की जरूरत नहीं है dictजो इसे एक छोटे से तेज करना चाहिए

दूसरा dictअंदर locals()और फिर से दिखता है और globals()बिल्टिन को ढूंढता है, इसलिए आप dictउदाहरण के लिए एक स्थानीय कॉल को परिभाषित करके व्यवहार को बदल सकते हैं, हालांकि मैं कहीं भी नहीं सोच सकता कि यह डिबगिंग के अलावा शायद एक अच्छा विचार होगा।


4
एक उदाहरण जहां स्थानीय कहा जाता है उपयोगी हो सकता है: stackoverflow.com/a/7880276/313113
काटो

मेरा मानना ​​है कि तानाशाही () का उपयोग करने से पहले तर्कों के लिए एक तानाशाही का निर्माण होगा () और फिर वास्तविक तानाशाही के लिए एक दूसरी तानाशाही पैदा होगी। ब्रेसिज़ एक कदम में तानाशाही उदाहरण बनाता है।
नीलगाय

56

शाब्दिक बहुत तेज है, क्योंकि यह सामान्य CALL_FUNCTION के बजाय अनुकूलित BUILD_MAP और STORE_MAP ऑपकोड का उपयोग करता है:

> python2.7 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)"
1000000 loops, best of 3: 0.958 usec per loop

> python2.7 -m timeit "d = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}"
1000000 loops, best of 3: 0.479 usec per loop

> python3.2 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)"
1000000 loops, best of 3: 0.975 usec per loop

> python3.2 -m timeit "d = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}"
1000000 loops, best of 3: 0.409 usec per loop

10
@ नीड: अधिकांश उपयोगकर्ताओं के लिए अधिकांश समय यह कोई मायने नहीं रखता है, लेकिन ऐसी परिस्थितियां हैं जहां लाखों या अरबों का निर्माण हो रहा है और एक 2x स्पीडअप सार्थक है।
श्री फूज

5
@MrFooz: उस तरह के हालात हैं। मुझे लगता है कि आप पाएंगे कि माइक्रो-टाइमिंग करने वाले 99.9% लोग उन स्थितियों में नहीं हैं।
नेड बाचेल्ड 16

29
@ यह एक धागा है जो एक तेजी से हालांकि पूछ रहा है में उचित है।
इलियट

11
@ ईलियट ओपी ने यह नहीं पूछा कि कौन सा तेज है।
टॉम फर्ग्यूसन

5
यदि आप या तो लाखों डाइक का उत्पादन कर रहे हैं या लाखों की चाबी के साथ एक तानाशाह, अपने स्रोत में तानाशाहों से, आप इसे गलत कर रहे हैं।
jwg

41

वे पायथन 3.2 पर बहुत ज्यादा दिखते हैं।

जैसा कि गिब्बलर ने बताया, पहले देखने की जरूरत नहीं है dict, जो इसे थोड़ा तेज करना चाहिए।

>>> def literal():
...   d = {'one': 1, 'two': 2}
...
>>> def constructor():
...   d = dict(one='1', two='2')
...
>>> import dis
>>> dis.dis(literal)
  2           0 BUILD_MAP                2
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 ('one')
              9 STORE_MAP
             10 LOAD_CONST               3 (2)
             13 LOAD_CONST               4 ('two')
             16 STORE_MAP
             17 STORE_FAST               0 (d)
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE
>>> dis.dis(constructor)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('one')
              6 LOAD_CONST               2 ('1')
              9 LOAD_CONST               3 ('two')
             12 LOAD_CONST               4 ('2')
             15 CALL_FUNCTION          512
             18 STORE_FAST               0 (d)
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE

ध्यान दें कि कुछ कार्यान्वयनों में, यह वास्तव में "छोटा सा" नहीं है, 100 के एक कारक की तरह:$ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' "{'a': 1, 'b': 2, 'c': 3}" ....... Mean +- std dev: 1.73 ns +- 0.14 ns $ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' '{k:v for k,v in i}' ....... Mean +- std dev: 139 ns +- 10 ns $ pypy -m perf timeit -l '1000000' -n '5' -s 'i=(("a",1), ("b", 2), ("c", 3))' 'dict(i)' ....... Mean +- std dev: 188 ns +- 16 ns
DylanYoung

13

जैसा कि आपने उल्लेख किया है, ये दो दृष्टिकोण समान शब्दकोशों का उत्पादन करते हैं, जहां पायथन के शाब्दिक नियम हस्तक्षेप करते हैं।

शब्दकोश शाब्दिक कुछ अधिक स्पष्ट रूप से शब्दकोष हैं, और आप किसी भी प्रकार की कुंजी बना सकते हैं, लेकिन आपको प्रमुख नामों को उद्धृत करने की आवश्यकता है। दूसरी ओर, यदि आप किसी कारण से जरूरत पड़ती हैं, तो आप चाबियों के लिए चर का उपयोग कर सकते हैं:

a = "hello"
d = {
    a: 'hi'
    }

dict()निर्माता आप इनपुट के रूपों लेता है की विविधता की वजह से और अधिक लचीलापन देता है। उदाहरण के लिए, आप इसे जोड़े के एक पुनरावृत्तिकर्ता के साथ प्रदान कर सकते हैं, और यह उन्हें कुंजी / मूल्य जोड़े के रूप में मानेंगे।

मुझे कोई अंदाजा नहीं है कि PyCharm एक फॉर्म को दूसरे में बदलने की पेशकश क्यों करेगा।


2
खैर, मुझे लगता है कि PyCharm अभी अतिरिक्त अच्छा बनने की कोशिश कर रहा है। बस के रूप में यह हमेशा के लिए दोहरे उद्धरण में एकल उद्धृत तार बदलने की पेशकश करने के लिए लगता है - बिना किसी स्पष्ट कारण के।
मालीग्री 12

1
यदि आपकी चाबियाँ तार हैं, तो आपको केवल अपनी चाबियाँ उद्धृत करने की आवश्यकता है। वे बस आसानी से फ्लोट्स के फ्रोज़ेन्सेट्स के टपल्स हो सकते हैं, हालांकि यह थोड़ा बदसूरत हो सकता है।
वूल

7

अजगर 3.4 + pycharm के साथ एक बड़ा अंतर यह है कि यदि कुंजियों की संख्या 256 से अधिक हो जाती है, तो तानाशाह () निर्माता "वाक्यविन्यास त्रुटि" संदेश पैदा करता है।

मैं अब हुकुम का इस्तेमाल करना पसंद करता हूं।


3
यह सिर्फ अजगर 3.4 नहीं है। ऐसा इसलिए है क्योंकि सीपीथॉन <3.7 में अधिकतम 255 शाब्दिक तर्क हैं जो एक कॉल करने योग्य के लिए पारित किए गए हैं। ( stackoverflow.com/a/8932175/2718295 )
काउबरी

6

अजगर 2.7 ट्यूटोरियल से:

ब्रेसिज़ की एक जोड़ी एक खाली शब्दकोश बनाती है: {}। कुंजी के अल्पविराम से अलग सूची रखने: ब्रेसिज़ के भीतर मूल्य जोड़े प्रारंभिक कुंजी जोड़ता है: शब्दकोश में मूल्य जोड़े; यह आउटपुट पर लिखे गए तरीके भी हैं।

tel = {'jack': 4098, 'sape': 4139}
data = {k:v for k,v in zip(xrange(10), xrange(10,20))}

जबकि:

तानाशाह () कंस्ट्रक्टर ट्यूल के रूप में संग्रहीत कुंजी-मूल्य जोड़े की सूची से सीधे शब्दकोश बनाता है। जब जोड़े एक पैटर्न बनाते हैं, तो सूची बोध महत्वपूर्ण रूप से कुंजी-मूल्य सूची को निर्दिष्ट कर सकता है।

tel = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127}
data = dict((k,v) for k,v in zip(xrange(10), xrange(10,20)))

जब चाबियाँ सरल तार होती हैं, तो कभी-कभी कीवर्ड तर्क का उपयोग करके जोड़े निर्दिष्ट करना आसान होता है:

dict(sape=4139, guido=4127, jack=4098)
>>>  {'sape': 4139, 'jack':4098, 'guido': 4127}

तो दोनों {} और तानाशाही () शब्दकोश का उत्पादन करते हैं लेकिन शब्दकोश डेटा आरंभीकरण के कुछ अलग तरीके प्रदान करते हैं।


3

मैं d = {'one': '1'}चीजों को मूल्यों को निर्दिष्ट करने और उन्हें dict()निर्माणकर्ता को भेजने के बजाय तानाशाही को बहुत अधिक पठनीय, आपके परिभाषित डेटा के रूप में पाता हूं ।

दूसरी तरफ मैंने देखा है कि लोगों ने हुकुम को शाब्दिक रूप दिया है d = {'one', '1'} जो आधुनिक अजगर 2.7+ में एक सेट बनाएगा।

इसके बावजूद मैं अभी भी सभी तरीकों से सेट शाब्दिक का उपयोग करना पसंद करता हूं, क्योंकि मुझे लगता है कि इसकी अधिक पठनीय, व्यक्तिगत पसंद मुझे लगता है।


मैं नियमित रूप से भूल जाता हूं कि एस के लिए शाब्दिक वाक्यविन्यास setमौजूद है। मेरी इच्छा है कि ऑर्डर किए गए डक्ट्स के लिए एक शाब्दिक वाक्यविन्यास था ... बहुत यकीन है कि मैं उन्हें सेटों की तुलना में अधिक बार उपयोग करता हूं।
ArtOfWarfare

2

जब आप किसी और चीज़ (कोई भी अजगर) से चिपकाने वाले मूल्यों के प्रति श्रुत () शाब्दिक अच्छा हो, उदाहरण के लिए पर्यावरण चर की एक सूची। अगर आपके पास बैश फाइल थी, तो कहिए

FOO='bar'
CABBAGE='good'

आप आसानी से एक dict()शाब्दिक में पेस्ट कर सकते हैं और टिप्पणी जोड़ सकते हैं। यह विपरीत करना आसान बनाता है, कुछ और में कॉपी करता है। जबकि {'FOO': 'bar'}अजगर और जोंस के लिए वाक्य रचना बहुत ही अनोखी है। इसलिए यदि आप json का बहुत अधिक उपयोग करते हैं, तो आप {}दोहरे उद्धरण चिह्नों के साथ शाब्दिक उपयोग करना चाह सकते हैं ।


2

अतिरिक्त तरीकों के साथ ताना-विरासत वाली कक्षाएं, कस्टम तानाशाह कक्षाएं बनाने के लिए कोई शाब्दिक शाब्दिक नहीं है। इस तरह के मामले में कस्टम तानाशाह वर्ग निर्माता का उपयोग किया जाना चाहिए, उदाहरण के लिए:

class NestedDict(dict):

    # ... skipped

state_type_map = NestedDict(**{
    'owns': 'Another',
    'uses': 'Another',
})

0

इस तथ्य पर भी विचार करें कि ऑपरेटर्स के लिए मिलान करने वाले टोकन का उपयोग कंस्ट्रक्टर सिंटैक्स में नहीं किया जा सकता है, अर्थात डैशरीज़ कीज़।

>>> dict(foo-bar=1)
File "<stdin>", line 1
SyntaxError: keyword can't be an expression

>>> {'foo-bar': 1}
{'foo-bar': 1}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.