অভিধান থেকে কোনও আইটেম সরান যখন এর কীটি অজানা


112

মান দ্বারা অভিধান থেকে কোনও আইটেম সরানোর সর্বোত্তম উপায় কী, যখন যখন আইটেমটির কীটি অজানা থাকে? এখানে একটি সহজ পদ্ধতি:

for key, item in some_dict.items():
    if item is item_to_remove:
        del some_dict[key]

আরও ভাল উপায় আছে? অভিধানটি পুনরুক্ত করার সময় অভিধান থেকে পরিবর্তন (আইটেমগুলি মোছা) করার কি কোনও সমস্যা আছে?


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

উত্তর:


92

সচেতন থাকুন যে আপনি বর্তমানে অবজেক্টের পরিচয়ের জন্য পরীক্ষা করছেন ( isকেবলমাত্র Trueযদি দুটি অপারেন্ড মেমোরিতে একই বস্তু দ্বারা প্রতিনিধিত্ব করা হয় - এটি সর্বদা দুটি বস্তুর সাথে সমান তুলনা করে না তবে ==)। আপনি যদি উদ্দেশ্য অনুযায়ী এটি করছেন, তবে আপনি নিজের কোডটি আবার লিখতে পারেন

some_dict = {key: value for key, value in some_dict.items() 
             if value is not value_to_remove}

তবে এটি আপনি যা চান তা করতে পারে না:

>>> some_dict = {1: "Hello", 2: "Goodbye", 3: "You say yes", 4: "I say no"}
>>> value_to_remove = "You say yes"
>>> some_dict = {key: value for key, value in some_dict.items() if value is not value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 3: 'You say yes', 4: 'I say no'}
>>> some_dict = {key: value for key, value in some_dict.items() if value != value_to_remove}
>>> some_dict
{1: 'Hello', 2: 'Goodbye', 4: 'I say no'}

সুতরাং আপনি সম্ভবত !=পরিবর্তে চান is not


2
এটি কি অভিধান সংক্ষেপণ? এগুলি কখন যুক্ত হয়েছিল?
বাটনস 840

4
আপনি ব্যবহার করতে পারে some_dict.iteritems()এখানে এবং করা forএবং ifপাঠযোগ্যতা জন্য পৃথক লাইন বিবৃতি
JFS

3
আমি বিশ্বাস করি পাইথন ২.7 এ অভিধান বোঝার যোগ করা হয়েছিল।
মিত্রাণ্ডি

2
@ জেএফ সেবাস্তিয়ান: আমি পাইথন 3 এ আছি এবং iteritemsএখন আছি items। পাইথন ২.7- iteritems()এ প্রকৃতপক্ষে আরও ভাল।
টিম পিটজ্যাকার

1
@ বাটনস 840 এগুলিকে পিইপি 274 বা অভিধানের ডিসপ্লেতে ডিক সংজ্ঞা বলা হয় । পিইপি হিসাবে বলা হয়েছে যে তারা ২.7-তে ব্যাকপোর্টেড ৩.x ফাইট হিসাবে যুক্ত হয়েছিল । বিকল্পভাবে আপনি dict()উপযুক্ত জেনারেটর এক্সপ্রেশন দিয়ে খাওয়াতে পারবেন , যা 2.4। মেটা: জিনিস খুঁজে বের করার জন্য এখানে পিপগুলি ব্রাউজ করতে পারে।
n611x007

120

dict.pop(key[, default])পদ্ধতি আইটেমগুলি সরানোর যখন আপনি কী জানেন পারেন। এটি আইটেমটি সরিয়ে ফেললে কীটিতে মানটি ফেরত দেয় অন্যথায় এটি যা পাস হয় তা ফিরিয়ে দেয় defaultদস্তাবেজগুলি দেখুন ''

উদাহরণ:

>>> dic = {'a':1, 'b':2}
>>> dic
{'a': 1, 'b': 2}
>>> dic.pop('c', 0)
0
>>> dic.pop('a', 0)
1
>>> dic
{'b': 2}

4
কী কখন অজানা তা সম্পর্কিত ওপিকে জিজ্ঞাসা করা হয়েছে
nmz787


42

ডেল এবং পপ () এর মধ্যে একটি সাধারণ তুলনা :

import timeit
code = """
results = {'A': 1, 'B': 2, 'C': 3}
del results['A']
del results['B']
"""
print timeit.timeit(code, number=100000)
code = """
results = {'A': 1, 'B': 2, 'C': 3}
results.pop('A')
results.pop('B')
"""
print timeit.timeit(code, number=100000)

ফলাফল:

0.0329667857143
0.0451040902256

সুতরাং, ডেল পপ () এর চেয়ে দ্রুত ।


6
তবে, পারফরম্যান্সের পার্থক্যটি দুর্দান্ত নয় এবং আপনি যদি কোনও ব্যতিক্রম বাড়াতে চান তবে আপনি দ্বিতীয় তর্কটি সরবরাহ করতে পারেন pop()(যেমন @ এন-1-1 উপরে রয়েছে) - যা delঅপারেটরের পক্ষে কোনও বিকল্প নয় ।
অ্যালেক্স ডুপুয়

1
প্রশ্নের সাথে আনুষাঙ্গিক, তবে আমি বুঝতে চেষ্টা করছি timeit। এই পরিষ্কার উদাহরণ জন্য আপনাকে ধন্যবাদ।
আদম_জি

কী কখন অজানা তা সম্পর্কে ওপি জিজ্ঞাসা করেছেন। এই উত্তরটি ধরে নিয়েছে কীটি জানা যায়।
জিন-ফ্রানসোয়া কার্বেট

7

items()একটি তালিকা ফেরত দেয়, এবং এটি সেই তালিকাটি যা আপনি পুনরাবৃত্তি করছেন তাই লুপে ডিকটি রূপান্তর করা এখানে গুরুত্বপূর্ণ নয়। আপনি যদি এর iteritems()পরিবর্তে ব্যবহার করে থাকেন তবে লুপটিতে ডিকটি পরিবর্তন করা সমস্যাযুক্ত হবে এবং একইভাবে viewitems()পাইথন ২.7- এও ।

আমি মান অনুসারে ডিক থেকে আইটেমগুলি সরিয়ে দেওয়ার আরও ভাল উপায় সম্পর্কে ভাবতে পারি না।


7

আমি কীগুলির একটি তালিকা তৈরি করব যা অপসারণের প্রয়োজন, তারপরে সেগুলি সরিয়ে ফেলুন। এটি সহজ, দক্ষ এবং একসাথে পুনরাবৃত্তি এবং ডিকটি পরিবর্তনের বিষয়ে কোনও সমস্যা এড়ানো।

keys_to_remove = [key for key, value in some_dict.iteritems()
                  if value == value_to_remove]
for key in keys_to_remove:
    del some_dict[key]

কী কখন অজানা তা সম্পর্কে ওপি জিজ্ঞাসা করেছেন। এই উত্তরটি ধরে নিয়েছে কীটি জানা যায়।
জিন-ফ্রানসোয়া কার্বেট


1
y={'username':'admin','machine':['a','b','c']}
if 'c' in y['machine'] : del y['machine'][y['machine'].index('c')]

0

আপনার প্রস্তাব অনুসারে পুনরাবৃত্তি করার সময় অভিধান থেকে আইটেমগুলি মুছতে কোনও ভুল নেই। একসাথে একই অভিধান ব্যবহার করে একাধিক থ্রেড সম্পর্কে সতর্কতা অবলম্বন করুন, যার ফলে কী-ইরর বা অন্যান্য সমস্যা হতে পারে।

অবশ্যই ডকসটি http://docs.python.org/library/stdtypes.html#typsmapping এ দেখুন


for k,v in d.iteritems(): del d[k]দিতে হবে RuntimeError: dictionary changed size during iteration। দেখুন মিতরন্দির ব্যাখ্যা।
বাটনস 840

1
অবশ্যই, d.iteitems () মূল পোস্টারটি কীভাবে পুনরাবৃত্তি হয় তা নয় এবং আমি আমার উত্তরে যা উল্লেখ করছি তা নয়।
থান সংগীত

0

এইভাবে আমি এটি করব।

for key in some_dict.keys():
    if some_dict[key] == item_to_remove:
        some_dict.pop(key)
        break
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.