ডিক আক্ষরিক এবং ডিক নির্মাণকারী ব্যবহারের মধ্যে কি পার্থক্য রয়েছে?


204

পাইচার্ম ব্যবহার করে, আমি লক্ষ্য করেছি যে এটি ডিককে আক্ষরিক রূপান্তরিত করার প্রস্তাব দেয় :

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

একটি মধ্যে অভি কন্সট্রাকটর :

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

এই বিভিন্ন পদ্ধতির কিছু উল্লেখযোগ্য উপায়ে আলাদা?

(এই প্রশ্নটি লেখার সময় আমি লক্ষ্য করেছি যে dict()এটির ব্যবহার করে একটি সংখ্যার কীটি নির্দিষ্ট করা অসম্ভব বলে মনে হচ্ছে .. d = {1: 'one', 2: 'two'}সম্ভবত সম্ভব, তবে সম্ভবত এটি সম্ভব dict(1='one' ...)নয় else অন্য কিছু?)


4
dict()কী-মান সংযোজনগুলির তালিকা তৈরি করার পাশাপাশি নামকরণকৃত প্যারামিটারগুলির অনুমতি দেয়, সুতরাং এটি আপনি যে সিনট্যাক্সটি ব্যবহার করছেন তা নয়, কোনও প্রকার ডিক তৈরি করতে ব্যবহার করতে পারে। পাইকার্মে একটি বাগ ( youtrack.jetbrains.net/issue/PY-2512 ) সম্ভবত ছিল যা আপনি আবিষ্কার করেছেন, যা সংশোধন করা হয়েছে তার কারণেই এটি সম্ভবত মূল্যবান নয় ।
ভুবল

1
সম্পর্কিত: stackoverflow.com/questions/5790860/... : (সারাংশ PyCharm আচরণ ধীর এবং uglier হয়)
Wooble

1
দৃশ্যত সিপিথন 2.7 ডিক () ধীর (6 গুণ ধীর?) দেখুন: ডউগহেলম্যান ডটকম / ২০১২ / ১১ / any যে কোনও ক্ষেত্রে আমি যেভাবেই কনস্ট্রাক্টর সিনট্যাক্সকে পছন্দ করতে শুরু করছি যেহেতু আমার কাছে ডিক্টস এবং ফাংশন কলগুলির মধ্যে কোড টাইপ করা এবং সরানো সহজ মনে হয়েছে।
ডেভিড হুইটন

2
স্পেস ভুলে যাবেন না: আপনি দ্বিতীয় উপায় ব্যবহার করে স্পেস থাকা কীগুলি তৈরি করতে পারবেন না। যদিও প্রথম উপায়টি যে কোনও স্ট্রিং নিতে পারে, এটি পাত্তা দেয় না। অবশ্যই এটি ইউনিকোডের ক্ষেত্রে প্রযোজ্য।
ক্যামিলবি

2
পাইথন 2-এ, dict(abc = 123)কনস্ট্রাক্টর বাইট-স্ট্রিং কী সহ একটি অভিধান তৈরি করে 'abc', আপনি যদি unicode_literalsঅভিধান কীগুলি ইউনিকোড হিসাবে ব্যবহার করে এবং প্রত্যাশা করেন তবে অবাক হতে পারে u'abc'স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 20357210/ … দেখুন ।
লি-অং ইপ

উত্তর:


116

আমি মনে করি আপনি সবচেয়ে সুস্পষ্ট পার্থক্য চিহ্নিত করেছেন। সেটা থেকে পৃথক,

প্রথমটির dictজন্য এটি দেখার দরকার নেই যা এটিকে সামান্য কিছুটা দ্রুততর করে তুলবে

দ্বিতীয় সৌন্দর্য আপ dictমধ্যে locals()এবং তারপর globals()এবং খুঁজে বের করে builtin, তাই আপনি একটি স্থানীয় নামক সংজ্ঞা আচরণ পাল্টাতে পারেন dictউদাহরণস্বরূপ যদিও আমি কোথাও মনে করতে পারেন না এই একটি ভাল ধারণা পৃথক্ হয়তো থেকে, যখন ডিবাগিং হবে


4
যেখানে একটি স্থানীয় নামক অভি উপযোগী হতে পারে একটি উদাহরণ: stackoverflow.com/a/7880276/313113
bitek

আমি বিশ্বাস করি যে ডিক () ব্যবহার করে ডিক () আর্গুমেন্টের জন্য প্রথমে একটি ডিক তৈরি করবে এবং তারপরে প্রকৃত ডিকের উদাহরণ তৈরি হওয়ার জন্য একটি দ্বিতীয় ডিক তৈরি করবে। ধনুর্বন্ধনী এক পদক্ষেপে ডক উদাহরণ তৈরি করে।
নীলজি

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
@ মিঃফুজ: এমন পরিস্থিতি রয়েছে। আমি মনে করি আপনি খুঁজে পাবেন যে 99.9% লোকেরা মাইক্রো-টাইমিংগুলি করেন না এমন পরিস্থিতিতে নেই।
নেড ব্যাচেল্ডার

29
@ নেড এটি একটি থ্রেডে প্রাসঙ্গিক যা জিজ্ঞাসা করছে যে কোনটি দ্রুততর।
এলিয়ট

11
@ এলিয়ট ওপি কোনটি দ্রুত তা জিজ্ঞাসা করেনি।
টম ফার্গুসন

5
যদি আপনি আপনার উত্সের ডিক্টর লিটারাল থেকে মিলিয়ন ডিক বা মিলিয়ন কী দ্বারা একটি ডিক উত্পাদন করে থাকেন তবে আপনি এটি ভুল করছেন।
jwg

41

পাইথন ৩.২-এ তারা দেখতে অনেকটা একইরকম।

গিনিবলারের নির্দেশ অনুসারে, প্রথমে অনুসন্ধানের দরকার নেই 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
ডিলান ইয়ং

13

এই দুটি পদ্ধতির অনুরূপ অভিধান তৈরি করা হয়েছে, যেমনটি আপনি উল্লেখ করেছেন, ব্যতীত পাইথনের লিক্সিক বিধিগুলি হস্তক্ষেপ করে।

অভিধানের আক্ষরিকাগুলি হ'ল আরও স্পষ্টত অভিধান, এবং আপনি যে কোনও ধরণের কী তৈরি করতে পারেন তবে আপনাকে মূল নামগুলি উদ্ধৃত করতে হবে। অন্যদিকে, যদি আপনার কোনও কারণে প্রয়োজন হয় তবে আপনি কীগুলির জন্য ভেরিয়েবলগুলি ব্যবহার করতে পারেন:

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

dict()কন্সট্রাকটর আপনি ইনপুট ফর্ম এটা লাগে ভিন্নতার কারনে আরো নমনীয়তা দেয়। উদাহরণস্বরূপ, আপনি এটি জোড়াগুলির একটি পুনরুক্তি সরবরাহ করতে পারেন, এবং এটি তাদের কী / মান জোড়া হিসাবে বিবেচনা করবে।

পাইকার্ম কেন একটি ফর্মকে অন্য রূপে রূপান্তর করার প্রস্তাব দেয় তা আমার কোনও ধারণা নেই।


2
ওয়েল, আমি অনুমান পাইচারম কেবল অতিরিক্ত সুন্দর হওয়ার চেষ্টা করছে। এটি সর্বদা মনে হয় একক-উদ্ধৃত স্ট্রিংগুলিকে ডাবল-কোটে রূপান্তরিত করার প্রস্তাব দেয় - কোনও আপাত কারণ ছাড়াই।
ম্যালিগ্রি

1
আপনার কীগুলি স্ট্রিং হলে কেবল আপনার কীগুলি উদ্ধৃত করতে হবে। এগুলি সহজেই ভাসমান ফ্রিজেসেন্টগুলির দ্বিগুণ হতে পারে যদিও এটি কিছুটা কুৎসিত হতে পারে।
Wooble

7

পাইথন ৩.৪ + পাইচার্মের সাথে একটি বড় পার্থক্য হ'ল ডিক () নির্মাণকারী একটি "সিনট্যাক্স ত্রুটি" বার্তা উত্পন্ন করে যদি কীগুলির সংখ্যা 256 এর বেশি হয় ce

আমি এখন ডিকটি আক্ষরিক ব্যবহার পছন্দ করি।


3
এটি শুধু অজগর 3.4 নয় 4 এটি কারণ সিপিথন <3.7 এর একটি কলযোগ্যকে সর্বাধিক 255 আক্ষরিক যুক্তি রয়েছে passed ( Stackoverflow.com/a/8932175/2718295 )
cowbert

6

পাইথন ২.7 টি টিউটোরিয়াল থেকে:

একজোড়া ধনুর্বন্ধনী একটি খালি অভিধান তৈরি করে: {}} কমাটির দ্বারা পৃথকীকরণের একটি কী স্থাপন করা: ধনুর্বন্ধনীগুলির মধ্যে মান জোড় প্রাথমিক কী যুক্ত করে: অভিধানে মান জোড়; আউটপুটে অভিধানগুলিও এইভাবে লেখা হয়।

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

যদিও:

ডিক () নির্মাতা টিপলস হিসাবে সঞ্চিত কী-মান জোড়ার তালিকাগুলি থেকে সরাসরি অভিধান তৈরি করে। জোড়গুলি যখন একটি প্যাটার্ন গঠন করে, তখন তালিকা বোঝার সংক্ষিপ্তভাবে কী-মান তালিকাটি নির্দিষ্ট করতে পারে specify

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'}যা আধুনিক অজগর ২.7++ সেট তৈরি করবে।

তবুও আমি এখনও সর্ব-উপায়ে সেটটি আক্ষরিক ব্যবহার করতে পছন্দ করি কারণ আমি মনে করি এটির আরও বেশি পঠনযোগ্য, ব্যক্তিগত পছন্দ।


আমি নিয়মিত ভুলে যাই যে এর জন্য আক্ষরিক বাক্য গঠন setরয়েছে। আমি ইচ্ছা করি অর্ডার করা ডিক্টসের জন্য একটি আক্ষরিক সিনট্যাক্স ছিল ... পুরোপুরি নিশ্চিত যে আমি সেটের চেয়ে বেশি বার সেগুলি ব্যবহার করি।
আর্টঅফ ওয়ারফেয়ার

2

ডিক্ট () আক্ষরিকটি দুর্দান্ত যখন আপনি অন্য কোনও কিছু থেকে মানগুলি আটকানোর (অজগর নয়) উদাহরণস্বরূপ পরিবেশ ভেরিয়েবলের একটি তালিকা। আপনার যদি বাশ ফাইল ছিল, বলুন

FOO='bar'
CABBAGE='good'

আপনি সহজেই এর পরে dict()আক্ষরিক মধ্যে আটকানো এবং মন্তব্য যুক্ত করতে পারেন । এটি বিপরীত কাজ করা আরও সহজ করে তোলে, অন্য কোনও কিছুতে অনুলিপি করে। অন্যদিকে {'FOO': 'bar'}সিনট্যাক্সটি পাইথন এবং জসন-এর কাছে বেশ অনন্য। সুতরাং আপনি যদি জসন প্রচুর ব্যবহার করেন তবে আপনি {}ডাবল উদ্ধৃতি সহ আক্ষরিক ব্যবহার করতে চাইতে পারেন ।


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}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.