পাইথন উপস্থিত না থাকলে ডিকে একটি কী আপডেট করে


104

আমি মুখ্য কী জোড় জোড় dictোকাতে চাই যদি ডিক.কিজে () না থাকে তবে dict মূলত আমি এটি দিয়ে করতে পারি:

if key not in d.keys():
    d[key] = value

তবে এর চেয়ে ভাল উপায় আর কি আছে? বা এই সমস্যার অজগর সমাধান কি?


উত্তর:


144

আপনার কল করার দরকার নেই d.keys(), তাই

if key not in d:
    d[key] = value

যথেষ্ট। এখানে আরও পরিষ্কার, বেশি পঠনযোগ্য পদ্ধতি নেই।

আপনি এর সাথে আবার আপডেট dict.get()করতে পারেন, যা কীটি ইতিমধ্যে উপস্থিত থাকলে বিদ্যমান মানটি ফিরিয়ে দেবে:

d[key] = d.get(key, value)

তবে আমি এর বিরুদ্ধে দৃ strongly়ভাবে সুপারিশ করছি; এটি হ'ল কোড গল্ফিং, রক্ষণাবেক্ষণ এবং পঠনযোগ্যতার প্রতিবন্ধকতা।


কোডটি ব্যবহার করে যদি আমার একাধিক থ্রেড থাকে তবে আমার কি এটি সিঙ্ক্রোনাইজ করার দরকার আছে?
এডি 22

4
@ এড 22 হ্যাঁ, কারণ এতে একাধিক বাইকোড নির্দেশ রয়েছে, যার মধ্যে থ্রেডগুলি পরিবর্তন করতে পারে।
মার্টিজন পিটারস

77

ব্যবহার dict.setdefault():

>>> d = {1: 'one'}
>>> d.setdefault(1, '1')
'one'
>>> d    # d has not changed because the key already existed
{1: 'one'}
>>> d.setdefault(2, 'two')
'two'
>>> d
{1: 'one', 2: 'two'}

4
dict.setdefault()মানটি খুব অ্যাক্সেস করার চেষ্টা করার সময় কেবল সত্যই ব্যবহার করা উচিত।
মার্টিজন পিটারস

11
@ মার্তিজন পিটারস: কেন বিষয়টি গুরুত্বপূর্ণ? নামটি setdefault()যা ঘটছে তা স্পষ্টভাবে বর্ণনা করে - এটি একটি মানও দেয় যে তা গুরুত্বপূর্ণ নয়, এবং একটি সামান্য উদ্বিগ্ন আইএমও। আপনি কেন একটি তাত্পর্য ব্যাখ্যা বা একটি লিঙ্ক প্রদান করতে পারেন কেন এটি পছন্দসই নয়?
মুহাক

6
আপনি এটিকে একটি অভিব্যক্তি হিসাবে ব্যবহার করবেন যা কোনও গ্রুপিং লুপের মতো: একটি মান বিদ্যমান বলে প্রত্যাশা করে for obj in iterable: d.setdefault(key_for_obj(obj), []).append(obj)। মানটি ফিরে আসার বিষয়ে কোন তাত্পর্যপূর্ণ কিছুই নেই , এটিই পদ্ধতির পুরো বিষয়
মার্টিজন পিটারস

4
এছাড়াও, এটি আপনি যা করার চেষ্টা করছেন তা অস্পষ্ট করে দেয়, যা ইতিমধ্যে উপস্থিত না থাকলে কেবল কোনও কী সেট করা হয়। পঠনযোগ্যতার গণনা, কেবল একটি if key not in d:পরীক্ষা ব্যবহার করুন ।
মার্টিজন পিটারস

6
@ মার্তিজজনপিটারস: ব্যাখ্যার জন্য ধন্যবাদ। ডক্টরসিং পড়ার পরে setdefault()মনে হয় আপনি যা বলেছিলেন সেটির দিকে তাকাতে হবে। একটি ব্যবহারের defaultdict(list)ফলে আপনার উদাহরণের চেয়ে বেশি পঠনযোগ্য কোড আসবে ... সুতরাং সম্ভবত স্ট্যান্ডার্ড অভিধান দিয়ে কাজ করা না হলে এটির জন্য কোনও ব্যবহার নেই for সামগ্রিকভাবে, আরও if key not in dপরিষ্কার।
mhakke

22

যেহেতু পাইথন 3.9 আপনি ব্যবহার করতে পারেন একত্রীকরণ অপারেটর | দুই অভিধান একত্রীকরণ। ডানদিকে ডিকটি অগ্রাধিকার নেয়:

d = { key: value } | d

দ্রষ্টব্য: এটি আপডেট হওয়া মানগুলির সাথে একটি নতুন অভিধান তৈরি করে।


4
যদিও এটি আকর্ষণীয়, তবে আমি এটি গৃহীত উত্তরের চেয়ে বেশি পঠনযোগ্য বলে মনে করি না
জাস্টিন ফুরনেস

আমার জন্য, এখন দুটি ডিক্টগুলি একীভূত করার উপায় আছে তা জানতে পেরে খুব ভাল লাগল
অস্টিন এ

5

নিম্নলিখিতগুলির সাহায্যে আপনি একাধিক মান সন্নিবেশ করতে এবং ডিফল্ট মান থাকতে পারে তবে আপনি একটি নতুন অভিধান তৈরি করছেন creating

d = {**{ key: value }, **default_values}

আমি এটি সর্বাধিক ভোট দেওয়া উত্তরের সাথে পরীক্ষা করেছি এবং এটি নিম্নোক্ত উদাহরণে দেখা যায় হিসাবে গড়ে এটি দ্রুততর হয়।

আনপ্যাক অপারেটরের সাথে ডিক বোঝার সাথে লুপ ভিত্তিক পদ্ধতির সাথে তুলনা করার গতি পরীক্ষা আনপ্যাক অপারেটর পদ্ধতির সাথে ডিক বোঝার সাথে লুপ ভিত্তিক পদ্ধতির সাথে তুলনা করার গতি পরীক্ষা।

d = default_vals.copy()প্রথম মামলায় যদি কোনও অনুলিপি ( ) তৈরি না করা হয় তবে একবার আমরা যখন 10**5আরও বেশি মাত্রার অর্ডারে পৌঁছায় তখন সর্বাধিক ভোট দেওয়া উত্তর দ্রুত হবে । উভয় পদ্ধতির মেমরির পদচিহ্ন একই।


4
তারপরে কেন এটি প্রথম স্থানে প্রস্তাব দিন
জোনাথন

4
এই সমাধানটি আমার কাছে পুরোপুরি বৈধ বলে মনে হচ্ছে। এটি এক ঘোষণায় একাধিক মান আপডেট করার অনুমতি দেয়।
রোটারেটি

তোমাকে অনেক ধন্যবাদ. তবে এটি হওয়া উচিত বলে মনে হচ্ছে{**default_values, **{ key: value }}
osexp2003

0

উপরের উত্তর অনুসারে সেটডিফল্ট () পদ্ধতিটি আমার পক্ষে কাজ করেছিল।

old_attr_name = mydict.setdefault(key, attr_name)
if attr_name != old_attr_name:
    raise RuntimeError(f"Key '{key}' duplication: "
                       f"'{old_attr_name}' and '{attr_name}'.")

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

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