python - গণিতের উৎপত্তি




কিভাবে একটি একক অভিব্যক্তি দুটি অভিধান একত্রিত করা? (20)

আমার দুটি পাইথন অভিধান আছে, এবং আমি একক অভিব্যক্তি লিখতে চাই যা এই দুটি অভিধানগুলিকে ফিরিয়ে দেয়। update() পদ্ধতিটি আমার প্রয়োজন হবে, যদি এটি পরিবর্তে পরিবর্তিত হওয়ার পরিবর্তে তার ফলাফলটি ফেরত দেয়।

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = x.update(y)
>>> print(z)
None
>>> x
{'a': 1, 'b': 10, 'c': 11}

আমি কিভাবে চূড়ান্ত একত্রীকৃত স্ব z , না x পারি?

(অতিরিক্ত স্পষ্ট হতে, dict.update() এর শেষ-এক-বিবাদ দ্বন্দ্ব-পরিচালনা যা আমি খুঁজছি।)


কিভাবে আমি একক এক্সপ্রেশনতে দুটি পাইথন অভিধান একত্রিত করতে পারি?

x এবং y অভিধানগুলির জন্য, z x থেকে যারা পরিবর্তে y থেকে মানগুলির সাথে একটি অগভীরভাবে মিশ্রিত অভিধান হয়ে ওঠে।

  • পাইথন 3.5 বা তার বেশি:

    z = {**x, **y}
    w = {'foo': 'bar', 'baz': 'qux', **y}  # merge a dict with literal values
    
  • পাইথন ২, (বা 3.4 বা তার কম) একটি ফাংশন লিখুন:

    def merge_two_dicts(x, y):
        z = x.copy()   # start with x's keys and values
        z.update(y)    # modifies z with y's keys and values & returns None
        return z
    

    এবং এখন:

    z = merge_two_dicts(x, y)
    

ব্যাখ্যা

বলুন আপনার দুটি ডিক্ট আছে এবং আপনি আসল ডিক্টগুলি পরিবর্তন না করেই তাদের নতুন শিরোনামে মার্জ করতে চান:

x = {'a': 1, 'b': 2}
y = {'b': 3, 'c': 4}

পছন্দসই ফলাফল একটি নতুন অভিধান ( z ) মান বিন্যস্ত সঙ্গে, এবং দ্বিতীয় dict এর মান প্রথম থেকে যারা overwriting পেতে হয়।

>>> z
{'a': 1, 'b': 3, 'c': 4}

এই জন্য একটি নতুন সিনট্যাক্স, পিইপি 448 এ প্রস্তাবিত এবং পাইথন 3.5 হিসাবে পাওয়া যায়

z = {**x, **y}

এবং এটি প্রকৃতপক্ষে একটি একক অভিব্যক্তি।

মনে রাখবেন যে আমরা আক্ষরিক নোটেশন সহ একত্রিত হতে পারি:

z = x.copy()
z.update(y) # which returns None since it mutates z

এবং এখন:

def merge_two_dicts(x, y):
    """Given two dicts, merge them into a new dict as a shallow copy."""
    z = x.copy()
    z.update(y)
    return z

এটি এখন 3.5, পিইপি 478 এর জন্য রিলিজের সময়সূচিতে বাস্তবায়িত হিসাবে দেখানো হচ্ছে, এবং এটি এখন পাইথন 3.5 ডকুমেন্টে কি হটস নিউতে প্রবেশ করেছে।

যাইহোক, যেহেতু অনেক সংস্থা এখনও পাইথন 2 তে রয়েছে, তাই আপনি এটি পূর্ববর্তী সামঞ্জস্যপূর্ণ ভাবে করতে পারেন। পাইথন 2 এবং পাইথন 3.0-3.4 এ প্রাপ্ত ক্লাসিক্যাল পাইথনিক উপায়টি দুই ধাপের প্রক্রিয়া হিসাবে এটি করতে হয়:

z = merge_two_dicts(x, y)

উভয় পন্থাতে, y দ্বিতীয় আসবে এবং এর মান x এর মানগুলি প্রতিস্থাপিত করবে, এইভাবে 'b' আমাদের চূড়ান্ত ফলাফলে 3 পয়েন্ট করবে।

পাইথন 3.5 তে এখনো নেই, কিন্তু একটি একক অভিব্যক্তি চাই

যদি আপনি পাইথন 3.5 তে এখনো না থাকেন, বা পশ্চাদপট-সামঞ্জস্যপূর্ণ কোড লিখতে চান, এবং আপনি এটি একটি একক অভিব্যক্তিতে চান তবে সঠিক পদ্ধতির সাথে সর্বাধিক পারফরম্যান্টটি একটি ফাংশনে রাখা হয়:

def merge_dicts(*dict_args):
    """
    Given any number of dicts, shallow copy and merge into a new dict,
    precedence goes to key value pairs in latter dicts.
    """
    result = {}
    for dictionary in dict_args:
        result.update(dictionary)
    return result

এবং তারপর আপনি একটি একক অভিব্যক্তি আছে:

z = merge_dicts(a, b, c, d, e, f, g) 

আপনি শূন্য থেকে খুব বড় সংখ্যায় ডিক্টগুলির অনির্ধারিত সংখ্যা একত্রিত করতে একটি ফাংশনও তৈরি করতে পারেন:

z = dict(x.items() + y.items())

এই ফাংশনটি সমস্ত ডিক্টের জন্য পাইথন 2 এবং 3 এ কাজ করবে। উদাহরণস্বরূপ a g থেকে dicts দেওয়া:

>>> c = dict(a.items() + b.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict_items' and 'dict_items'

এবং g কী মান জোড়া জোড়া dicts থেকে f তে অগ্রাধিকার পাবে, ইত্যাদি।

অন্যান্য উত্তর সমালোচনা

পূর্বে গৃহীত উত্তরগুলিতে আপনি যা দেখেন তা ব্যবহার করবেন না:

>>> c = dict(a.items() | b.items())

পাইথন 2 এ, আপনি প্রতিটি স্বর জন্য স্মৃতিতে দুটি তালিকা তৈরি করেন, মেমরির তৃতীয় তালিকাটি দৈর্ঘ্যের সমান দৈর্ঘ্যের সমান তালিকার সাথে তৈরি করুন, এবং তারপর তিনটি তালিকাকে টুকরা তৈরি করতে বাতিল করুন। পাইথন 3 এ, এটি ব্যর্থ হবে কারণ আপনি দুটি dict_items বস্তুগুলিকে একসাথে যুক্ত করছেন, দুটি তালিকা নয় -

>>> x = {'a': []}
>>> y = {'b': []}
>>> dict(x.items() | y.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

এবং আপনাকে তাদের তালিকা হিসাবে স্পষ্টভাবে তৈরি করতে হবে, যেমন z = dict(list(x.items()) + list(y.items())) । এটি সম্পদ এবং গণনার ক্ষমতা একটি বর্জ্য।

অনুরূপভাবে, পাইথন 3 (পাইথন 2.7) এ viewitems() 3 ( viewitems() items() -এর items() গ্রহণ করা হলে মানগুলি হ্রাসযোগ্য বস্তুর (উদাহরণস্বরূপ তালিকাগুলির মতো) ব্যর্থ হবে। এমনকি যদি আপনার মানগুলি হ্যাসেবল হয় তবে সেটগুলি শব্দগতভাবে অকার্যকর হয়, তবে আচরণ অগ্রাধিকারের ক্ষেত্রে অনির্ধারিত হয়। সুতরাং এটি করবেন না:

>>> x = {'a': 2}
>>> y = {'a': 1}
>>> dict(x.items() | y.items())
{'a': 2}

এই উদাহরণটি দেখায় যখন মানগুলি অসমর্থিত হয় তখন কী হয়?

z = dict(x, **y)

এখানে একটি উদাহরণ আছে যেখানে y অগ্রাধিকার থাকা উচিত, কিন্তু পরিবর্তে x থেকে মান সেটের ইচ্ছাকৃত অর্ডারের কারণে আটকে রাখা হয়:

>>> c = dict(a, **b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: keyword arguments must be strings

অন্য হ্যাক আপনি ব্যবহার করা উচিত নয়:

dict(a=1, b=10, c=11)

এটি dict কনস্ট্রাক্টর ব্যবহার করে এবং খুব দ্রুত এবং মেমরি দক্ষ (আমাদের দ্বি-পদক্ষেপের প্রক্রিয়া থেকেও কিছুটা বেশি) - কিন্তু যদি না আপনি সঠিকভাবে এখানে যা ঘটছে তা জানেন না (অর্থাৎ দ্বিতীয় শব্দটি কীওয়ার্ড আর্গুমেন্ট হিসাবে পাস করা হচ্ছে) dict constructor), এটি পড়া কঠিন, এটি ব্যবহারযোগ্য ব্যবহার নয়, এবং তাই এটি পাইথনিক নয়।

এখানে একটি উদাহরণ ব্যবহার করা হয় django মধ্যে remediated

ডিক্টগুলি হ্যাসেবল কী (যেমন ফোজেনসেট বা টিপল) নিতে ইচ্ছুক, তবে পাইথন 3 এ এই পদ্ধতিটি ব্যর্থ হয় যখন কী স্ট্রিং হয় না।

{'a': 1, 'b': 10, 'c': 11}

মেইলিং লিস্ট থেকে , ভাষা নির্মাতা গুইডো ভ্যান রসুম লিখেছেন:

আমি {{**, ** {1: 3}) অবৈধ ঘোষণার সাথে জরিমানা, কারণ এটি সর্বদা ** পদ্ধতির অপব্যবহার।

এবং

দৃশ্যত dict (x, ** y) "কল x.update (y) এবং ফিরে x" এর জন্য "শীতল হ্যাক" হিসাবে প্রায় চলছে। ব্যক্তিগতভাবে আমি শীতল চেয়ে আরো ঘৃণ্য খুঁজে।

এটা আমার বোঝার (পাশাপাশি ভাষাটির নির্মাতার বোঝা) যে dict(**y) উদ্দেশ্যে ব্যবহৃত পাঠ্যতাটি পাঠযোগ্যতার উদ্দেশ্যে ডিক্ট তৈরির জন্য হয়, উদাহরণস্বরূপ:

>>> foo(**{('a', 'b'): None})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() keywords must be strings
>>> dict(**{('a', 'b'): None})
{('a', 'b'): None}

পরিবর্তে

{k: v for d in dicts for k, v in d.items()} # iteritems in Python 2.7

মন্তব্য প্রতিক্রিয়া

Guido বলছে কি সত্ত্বেও, dict(x, **y) স্বর স্পেসিফিকেশানের সাথে সঙ্গতিপূর্ণ, যা btw। পাইথন 2 এবং 3 উভয়ের জন্য কাজ করে। এটি শুধুমাত্র স্ট্রিং কীগুলির জন্য কাজ করে যা কীওয়ার্ড প্যারামিটারগুলি কীভাবে কাজ করে এবং স্বতঃস্ফূর্ত শব্দ নয় তা সরাসরি ফলাফল। তাছাড়াও ** অপারেটরটি এই স্থানে যন্ত্রটির অপব্যবহার ব্যবহার করছে না, প্রকৃতপক্ষে ** কীওয়ার্ড হিসাবে ডিক্টগুলি পাস করার জন্য অবিকল ডিজাইন করা হয়েছে।

আবার, যখন এটি অ-স্ট্রিং থাকে তখন এটি 3 এর জন্য কাজ করে না। নিখুঁত কলিং চুক্তি হল নামস্থানগুলি সাধারণ ডিক্টগুলি গ্রহণ করে, ব্যবহারকারীদের শুধুমাত্র স্ট্রিংগুলির মধ্যে কীওয়ার্ড আর্গুমেন্টগুলি পাস করতে হবে। অন্যান্য সমস্ত কলএবল এটি কার্যকর। পাইথন ২ এ এই ধারাবাহিকতাটি ভেঙ্গে dict :

dict((k, v) for d in dicts for k, v in d.items())

এই অসঙ্গতিটি পাইথন (পিপি, জ্যথন, আয়রনপথন) এর অন্যান্য বাস্তবায়নের জন্য খারাপ ছিল। সুতরাং এটি পাইথন 3 এ সংশোধন করা হয়েছিল, কারণ এই ব্যবহারটি একটি বিরতি পরিবর্তন হতে পারে।

আমি আপনাকে জমা দিচ্ছি যে ইচ্ছাকৃতভাবে এমন কোড লিখতে দূষিত অসঙ্গতি যা কেবল একটি ভাষার একটি সংস্করণে কাজ করে বা শুধুমাত্র কিছু নির্দিষ্ট নির্বিচারে বাধা দেয়।

আরো মন্তব্য:

dict(x.items() + y.items()) এখনও Python 2 এর জন্য সর্বাধিক পঠনযোগ্য সমাধান। পাঠযোগ্যতা গণনা।

আমার প্রতিক্রিয়া: merge_two_dicts(x, y) আসলে আমার কাছে অনেক স্পষ্ট মনে হয়, যদি আমরা আসলেই পঠনযোগ্যতার বিষয়ে উদ্বিগ্ন। এবং এটি সামঞ্জস্যপূর্ণ নয়, পাইথন 2 ক্রমবর্ধমানভাবে বর্জন করা হয়।

{**x, **y} নেস্টেড অভিধানগুলি হ্যান্ডেল বলে মনে হচ্ছে না। নেস্টেড কীগুলির সামগ্রীগুলি কেবলমাত্র মুছে ফেলা হয়, মার্জ করা হয় না [...] আমি এই উত্তরগুলির দ্বারা পুড়িয়ে ফেলা শেষ করি যা পুনরাবৃত্তি করে না এবং আমি অবাক হতাম না যে কেউ এটি উল্লেখ করেনি। শব্দটি "মার্জিং" এর আমার ব্যাখ্যার মধ্যে এই উত্তরগুলি "অন্যের সাথে একটি dict আপডেট করা" বর্ণনা করে, এবং মার্জ করা হয় না।

হ্যাঁ। আমি আপনাকে অবশ্যই প্রশ্নটির সাথে যোগাযোগ করতে হবে, যা দুটি অভিধানের অগভীর একত্রের জন্য জিজ্ঞাসা করছে, প্রথমটির মানগুলি দ্বিতীয়টির দ্বারা ওভাররাইট করা হচ্ছে - একক অভিব্যক্তি।

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

import itertools
z = dict(itertools.chain(x.iteritems(), y.iteritems()))

ব্যবহার:

import timeit

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

কম পারফরম্যান্স কিন্তু সঠিক বিজ্ঞাপন হক্স

এই পদ্ধতির কম কর্মক্ষমতা, কিন্তু তারা সঠিক আচরণ প্রদান করবে। তারা copy এবং update বা নতুন অপপ্যাকিংয়ের তুলনায় অনেক কম পারফরম্যান্স করবে কারণ তারা প্রতিটি কী-মান জোড়া জুড়ে একটি উচ্চ স্তরের বিমূর্ততার সাথে পুনরাবৃত্তি করে, তবে তারা অগ্রাধিকারের আদেশকে সম্মান করে (পরবর্তী ডিক্টগুলির অগ্রাধিকার থাকে)

আপনি একটি স্বতন্ত্র বোঝার ভিতরে নিজে নিজে ডিক্টস করতে পারেন:

>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.5726828575134277
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.163769006729126
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.iteritems(), y.iteritems()))))
1.1614501476287842
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
2.2345519065856934

বা পাইথন 2.6 (এবং জেনারেটরের এক্সপ্রেশনগুলি উপস্থাপিত হওয়ার সাথে সাথে 2.4 হিসাবে প্রাথমিকভাবে):

>>> min(timeit.repeat(lambda: {**x, **y}))
0.4094954460160807
>>> min(timeit.repeat(lambda: merge_two_dicts(x, y)))
0.7881555100320838
>>> min(timeit.repeat(lambda: {k: v for d in (x, y) for k, v in d.items()} ))
1.4525277839857154
>>> min(timeit.repeat(lambda: dict(itertools.chain(x.items(), y.items()))))
2.3143140770262107
>>> min(timeit.repeat(lambda: dict((k, v) for d in (x, y) for k, v in d.items())))
3.2069112799945287

itertools.chain সঠিক ক্রমের কী-মান জোড়াগুলির উপর itertools.chain চেইন করবে:

z = dict(x.items() + y.items())

কর্মক্ষমতা বিশ্লেষণ

আমি কেবল সঠিকভাবে আচরণ করতে পরিচিত Usages কর্মক্ষমতা বিশ্লেষণ করতে যাচ্ছি।

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}

উবুন্টু 14.04 এ নিম্নলিখিত কাজ করা হয়েছে

পাইথন 2.7 (সিস্টেম পাইথন):

>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}

পাইথন 3.5 (পিএইচপি ডেডসনেকস):

z = x.copy()
z.update(y)

অভিধান উপর সম্পদ


Recursively / গভীর একটি dict আপডেট

x = {'a': 1, 'b': 1}
y = {'a': 2, 'c': 2}
final = {**x, **y} 
final
# {'a': 2, 'b': 1, 'c': 2}

প্রদর্শন:

final = {'a': 1, 'b': 1, **x, **y}

আউটপুট:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z

সম্পাদনার জন্য ধন্যবাদ rednaw।


আমি অনুরূপ কিছু চেয়েছিলাম, কিন্তু কিভাবে ডুপ্লিকেট কীগুলির মানগুলি একত্রিত করা হয়েছিল তা নির্দিষ্ট করার ক্ষমতা সহ, তাই আমি এটি হ্যাক করেছি (কিন্তু এটি ব্যাপকভাবে পরীক্ষা করে নি)। স্পষ্টতই এটি একটি একক অভিব্যক্তি নয়, তবে এটি একটি একক ফাংশন কল।

{
    'name': 'Pluutoo',
    'details': {
        'color': 'blue',
        'tail': True
    }
}

আরেকটি, আরো সংক্ষিপ্ত, বিকল্প:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'               
10000 loops, best of 3: 26.9 usec per loop

দ্রষ্টব্য : এটি একটি জনপ্রিয় উত্তর হয়ে উঠেছে, কিন্তু যদি এটিতে কোন অ স্ট্রিং কী থাকে তবে এটি উল্লেখ করা গুরুত্বপূর্ণ, এটি আসলেই কাজ করে যে এটি সিপিথন বাস্তবায়ন বিশদের অপব্যবহার এবং এটি পাইথন 3 তে কাজ করে না , বা পাইপিতে, আয়রনপথন বা জ্যথন। এছাড়াও, Guido একটি ফ্যান না । তাই আমি ফরোয়ার্ড-সামঞ্জস্যপূর্ণ বা ক্রস-বাস্তবায়নের পোর্টেবল কোডের জন্য এই কৌশলটি সুপারিশ করতে পারি না, যা আসলে সম্পূর্ণরূপে এড়ানো উচিত।


একটি বিকল্প:

% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)' 
100000 loops, best of 3: 1.53 usec per loop

এটি সম্ভবত একটি জনপ্রিয় উত্তর হবে না, তবে আপনি প্রায়শই এটি করতে চান না। যদি আপনি একটি কপি যা একটি কপি চান, তাহলে কপি (বা deepcopy কপি, আপনি যা চান তার উপর নির্ভর করে) ব্যবহার করুন এবং তারপরে আপডেট করুন। কোডের দুটি লাইনগুলি অনেক বেশি পঠনযোগ্য - আরও পাইথনিক - .items () + .items () সহ একক লাইন তৈরির চেয়ে। স্পষ্ট অন্তর্নিহিত চেয়ে ভাল।

উপরন্তু, যখন আপনি .items () (প্রাক পাইথন 3.0) ব্যবহার করেন, তখন আপনি একটি নতুন তালিকা তৈরি করছেন যা শিরোনামের আইটেমগুলি ধারণ করে। যদি আপনার অভিধানগুলি বড় হয়, তবে এটি বেশিরভাগ ওভারহেড (দুটি বৃহত তালিকা যা একত্রিত স্বর তৈরি হওয়ার সাথে সাথেই নিক্ষিপ্ত হবে)। আপডেট () আরও কার্যকরীভাবে কাজ করতে পারে, কারণ এটি দ্বিতীয় স্বতন্ত্র আইটেম-দ্বারা-আইটেমের মাধ্যমে চালাতে পারে।

time :

from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))

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


পাইথন 3 এ, items পদ্ধতি আর একটি তালিকা প্রদান করে না , বরং একটি দৃশ্য , যা একটি সেটের মত কাজ করে। এই ক্ষেত্রে আপনাকে সংযোজন করার পরে সেট ইউনিয়ন নিতে হবে + কাজ করবে না:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (x.update(y), x)[1]
>>> z
{'a': 1, 'b': 10, 'c': 11}

সংস্করণ 2.7 এ পাইথন 3-মত আচরণের জন্য, viewitems পদ্ধতি items জায়গায় কাজ করা উচিত:

import itertools as it
merge = lambda *args: dict(it.chain.from_iterable(it.imap(dict.iteritems, args)))

আমি এই সংকেত পছন্দ করি যেহেতু এটি কনট্যাটেনেশন (শিরোনাম শো হিসাবে) তুলনায় একটি সেট ইউনিয়ন অপারেশন হিসাবে এটি মনে আরো প্রাকৃতিক বলে মনে হয়।

সম্পাদনা:

পাইথনের জন্য আরও কয়েকটি পয়েন্ট 3. প্রথমত, মনে রাখবেন যে dict(x, **y) কৌশল পাইথন 3 তে কাজ করবে না যদি না y এর স্ট্রিং স্ট্রিং হয়।

এছাড়াও, রেমন্ড হেটিংয়ের চেনম্যাপের answer বেশ মার্জিত, কারণ এটি আর্গুমেন্ট হিসাবে ইচ্ছাকৃতভাবে ডিক্টগুলি নিতে পারে, তবে ডক্স থেকে এটি দেখে মনে হচ্ছে যে এটি প্রতিটি সন্ধানের জন্য সমস্ত ডিক্টগুলির একটি তালিকা অনুসরণ করে:

একটি কী পাওয়া না হওয়া পর্যন্ত অনুসন্ধানগুলি ক্রমাগত অন্তর্নিহিত ম্যাপিং অনুসন্ধান করে।

আপনার অ্যাপ্লিকেশনে প্রচুর সন্ধান থাকলে এটি আপনাকে হ্রাস করতে পারে:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> merge(x, y)
{'a': 1, 'b': 10, 'c': 11}

>>> z = {'c': 3, 'd': 4}
>>> merge(x, y, z)
{'a': 1, 'b': 10, 'c': 3, 'd': 4}

তাই অনুসন্ধানের জন্য ধীর গতির একটি আদেশ সম্পর্কে। আমি চেনম্যাপের একজন ফ্যান, কিন্তু অনেকগুলি সন্ধানের যেখানে কম ব্যবহারিক দেখায়।


পাইথন 3 এ, আপনি collections.ChainMap ব্যবহার করতে পারেন। চাইনMap যা একক, আপডেটযোগ্য দৃশ্য তৈরি করার জন্য একাধিক ডিক্ট বা অন্যান্য ম্যাপিংগুলিকে একত্র করে:

from itertools import chain
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
dict(chain(x.iteritems(), y.iteritems()))

পাইথনিক হতে। একটি comprehension ব্যবহার করুন:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = (lambda f=x.copy(): (f.update(y), f)[1])()
>>> z
{'a': 1, 'c': 11, 'b': 10}

যদি মনে হয় লাম্বড খারাপ হয় তবে আর পড়বেন না। অনুরোধ হিসাবে, আপনি একটি অভিব্যক্তি সঙ্গে দ্রুত এবং মেমরি দক্ষ সমাধান লিখতে পারেন:

In [1]: from collections import ChainMap
In [2]: from string import ascii_uppercase as up, ascii_lowercase as lo; x = dict(zip(lo, up)); y = dict(zip(up, lo))
In [3]: chainmap_dict = ChainMap(y, x)
In [4]: union_dict = dict(x.items() | y.items())
In [5]: timeit for k in union_dict: union_dict[k]
100000 loops, best of 3: 2.15 µs per loop
In [6]: timeit for k in chainmap_dict: chainmap_dict[k]
10000 loops, best of 3: 27.1 µs per loop

উপরে উল্লিখিত, দুটি লাইন ব্যবহার বা একটি ফাংশন লেখা সম্ভবত সম্ভবত একটি ভাল উপায়।


(পাইথন ২.7 * শুধুমাত্র * পাইথন 3 * এর জন্য সহজ সমাধান আছে।)

আপনি যদি কোনও স্ট্যান্ডার্ড লাইব্রেরী মডিউল আমদানি করতে বিরত না হন তবে আপনি তা করতে পারেন

 from functools import reduce def merge_dicts(*dicts): return reduce(lambda a, d: a.update(d) or a, dicts, {}) 

( প্রয়োজনীয় or aবিট সবসময় সাফল্যের উপর ফেরত lambdaকারণ ।)dict.updateNone


দুই অভিধান

a = { 'one': { 'depth_2': True }, 'two': True }
b = { 'one': { 'extra': False } }
print dict(a.items() + b.items())

এন অভিধান

{ 'one': { 'extra': False', 'depth_2': True }, 'two': True }

sumখারাপ কর্মক্ষমতা আছে। দেখুন https://mathieularose.com/how-not-to-flatten-a-list-of-lists-in-python/


এখানে এবং অন্য কোথাও ধারনাগুলি আঁকতে আমি একটি ফাংশনটি বুঝেছি:

0.049465 sec for: dict(x, **y)
0.033729 sec for: x.update(y)                   
0.150380 sec for: dict(x.items() + y.items())   
0.083120 sec for: for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]

confirm b elements are added: {'a': 1, 'c': 11, 'b': 12}

ব্যবহার (পাইথন 3 পরীক্ষিত):

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> { key: y[key] if key in y else x[key]
      for key in set(x) + set(y)
    }

আপনি পরিবর্তে একটি Lambda ব্যবহার করতে পারে।


এটি একটি একক স্বজ্ঞা বোঝার সাথে সম্পন্ন করা যেতে পারে:

 >>> x = {'a':1, 'b': 2} >>> y = {'b':10, 'c': 11} >>> { key: y[key] if key in y else x[key] for key in set(x) + set(y) } 

আমার দৃষ্টিতে 'একক অভিব্যক্তি' অংশটির জন্য কোনও অতিরিক্ত ফাংশন হিসাবে উত্তরের সেরা উত্তর প্রয়োজন নেই এবং এটি সংক্ষিপ্ত।


পাইথন 2 এর জন্য:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> x, z = dict(x), x.update(y) or x
>>> x
{'a': 1, 'b': 2}
>>> y
{'c': 11, 'b': 10}
>>> z
{'a': 1, 'c': 11, 'b': 10}

পাইথন 3 এর জন্য:

import timeit

n=100000
su = """
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
"""

def timeMerge(f,su,niter):
    print "{:4f} sec for: {:30s}".format(timeit.Timer(f,setup=su).timeit(n),f)

timeMerge("dict(x, **y)",su,n)
timeMerge("x.update(y)",su,n)
timeMerge("dict(x.items() + y.items())",su,n)
timeMerge("for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k] ",su,n)

#confirm for loop adds b entries together
x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
for k in y.keys(): x[k] = k in x and x[k]+y[k] or y[k]
print "confirm b elements are added:",x

এটি আউটপুট দেয়: {'a': 1, 'c': 11, 'b': 10}



পাইথন 3.5 এ আপনি **নতুন অভিধান তৈরি করতে আনপ্যাক ব্যবহার করতে পারেন । এই পদ্ধতি অতীতে উত্তর দেখানো হয়েছে। এছাড়াও, এটি {}পরিবর্তে ব্যবহার করা ভাল dict()। কারণ {}একটি পাইথন আক্ষরিক এবং dict()একটি ফাংশন কল জড়িত।

 dict1 = {'a':1} dict2 = {'b':2} new_dict = {**dict1, **dict2} >>>new_dict {'a':1, 'a':2} 

যদিও উত্তরগুলি এই অগভীর অভিধানের জন্য ভাল ছিল , এখানে সংজ্ঞায়িত কোনও পদ্ধতি আসলে একটি গভীর অভিধান একত্রিত করে না।

উদাহরণ অনুসরণ করুন:

{'two': True, 'one': {'extra': False}}

এক ভালো কিছু ফলাফল আশা করবে:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items()+y.items())
print(z)

পরিবর্তে, আমরা এই পেতে:

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items()|y.items())
print(z)

'এক' এন্ট্রিটি অবশ্যই 'গভীরতা_2' এবং 'অতিরিক্ত' তার অভিধানের ভিতরে আইটেমগুলির মতো হওয়া উচিত যদি এটি সত্যিই একত্রিত হয়।

চেইন ব্যবহার করে, কাজ করে না:

def merge(*dicts, **kv): 
      return { k:v for d in list(dicts) + [kv] for k,v in d.items() }

ফলাফল স্বরূপ:

assert (merge({1:11,'a':'aaa'},{1:99, 'b':'bbb'},foo='bar')==\
    {1: 99, 'foo': 'bar', 'b': 'bbb', 'a': 'aaa'})

assert (merge(foo='bar')=={'foo': 'bar'})

assert (merge({1:11},{1:99},foo='bar',baz='quux')==\
    {1: 99, 'foo': 'bar', 'baz':'quux'})

assert (merge({1:11},{1:99})=={1: 99})

RCwesick যে গভীর একত্রিত এছাড়াও একই ফলাফল সৃষ্টি করে।

হ্যাঁ, এটি নমুনা অভিধানগুলিকে একত্রিত করতে কাজ করবে, তবে তাদের মধ্যে কোনটি একত্রিত করার জেনেরিক প্রক্রিয়া নয়। একবার আমি একটি বৈধ মার্জ করে একটি পদ্ধতি লিখতে পরে পরে এই আপডেট করব।


from collections import Counter
dict1 = {'a':1, 'b': 2}
dict2 = {'b':10, 'c': 11}
result = dict(Counter(dict1) + Counter(dict2))

z={i:d[i] for d in [x,y] for i in d}

>>> print z
{'a': 1, 'c': 11, 'b': 10}

যেমন ছায়াময় এবং সন্দেহজনক উত্তরগুলির মধ্যে, এই উজ্জ্বল উদাহরণটি পাইথনের ডিক্টগুলিকে একত্রিত করার একমাত্র এবং ভাল উপায়, জীবনটির জন্য স্বৈরশাসক গীডো ভ্যান রসুম নিজেই সমর্থন করেছেন! অন্য কেউ এই অর্ধেক প্রস্তাব, কিন্তু একটি ফাংশন এটি করা হয়নি।

dict(x.items() | y.items())

দেয়:

dict(x.viewitems() | y.viewitems())






merge