আমি কীভাবে চেক করব যে একাধিক কী একক পাসে ডিকের মধ্যে রয়েছে?


উত্তর:


363

ঠিক আছে, আপনি এটি করতে পারেন:

>>> if all (k in foo for k in ("foo","bar")):
...     print "They're there!"
...
They're there!

10
+1, গ্রেগের উত্তরের চেয়ে আমি এটি পছন্দ করি কারণ এটি আরও সংক্ষিপ্ত এবং দ্রুত (অপ্রাসঙ্গিক অস্থায়ী তালিকার কোনও বিল্ডিং নয়, এবং শর্ট সার্কিটের সম্পূর্ণ শোষণ)।
অ্যালেক্স মার্টেলি

4
আমি সমস্ত () এবং যে কোনও () পছন্দ করি। তারা এত অ্যালগরিদমকে এত বেশি পরিষ্কার করে তোলে।
হুগডব্রাউন

আমি শেষ পর্যন্ত এই সমাধানটি ব্যবহার করে শেষ করেছি। এটি বড় ডেটাসেটের জন্য সেরা বলে মনে হয়েছিল। 25 বা 30 টি কী বলার জন্য পরীক্ষা করার সময়।

4
এটি শর্ট সার্কিটের জন্য একটি ভাল সমাধান ধন্যবাদ, বিশেষত যদি পরীক্ষাটি প্রায়শই ব্যর্থ হয়; আপনি যদি একবারে আগ্রহের কীগুলির সেটটি তৈরি করতে না পারেন এবং এটি বেশ কয়েকবার যাচাই করতে পারেন তবে এই ক্ষেত্রে setউচ্চতর। যথারীতি ... এটি পরিমাপ করুন! -)
অ্যালেক্স মার্টেলি

আমি যখনই এটি "স্বাভাবিক" উপায়ের চেয়েও সুন্দর দেখায়, সমস্ত এবং এর সাথে বা এর সাথে ... এটি খুব সুন্দর কারণ এটি আপনি "সমস্ত" বা "যে কোনও" ব্যবহার করতে পারেন ... এছাড়াও আপনি যা করতে পারেন " আপনি যে পরীক্ষার জন্য চেষ্টা করছেন তার উপর নির্ভর করে কে ইন
ফু

123
if {"foo", "bar"} <= myDict.keys(): ...

আপনি যদি এখনও পাইথন 2 এ থাকেন তবে আপনি এটি করতে পারেন

if {"foo", "bar"} <= myDict.viewkeys(): ...

আপনি যদি এখনও সত্যিই একটি পুরানো পাইথন <= 2.6 setতে থাকেন তবে ডিকটি কল করতে পারেন , তবে সেটটি তৈরি করতে পুরো ডিকটিটি পুনরাবৃত্তি করবে এবং এটি ধীর গতিতে:

if set(("foo", "bar")) <= set(myDict): ...

ভাল লাগছে! আমি কেবল পছন্দ করি না তা হ'ল আপনাকে অস্থায়ী সেট তৈরি করতে হবে তবে এটি খুব কমপ্যাক্ট। সুতরাং আমি অবশ্যই বলতে হবে ... সেট ব্যবহার চমৎকার!
টেরেন্স হোলস

17
অজগর 3 এ আপনি বলতে পারেন set(("foo","bar")) <= myDict.keys()যা অস্থায়ী সেটটিকে এড়িয়ে চলে, তাই অনেক দ্রুত। আমার পরীক্ষার জন্য কোয়েরিটি 10 ​​আইটেম ছিল তখন সমস্ত ব্যবহার করার মতোই গতি সম্পর্কে। যদিও কোয়েরিটি বড় হওয়ার সাথে সাথে এটি ধীর হয়ে যায়।
জন লা রুই

1
আমি উত্তর হিসাবে আমার কিছু পরীক্ষা পোস্ট করেছি। stackoverflow.com/questions/1285911/…
জন লা রো

30
if {'foo', 'bar'} <= set(myDict): ...
বরিস রাইচিফ

11
ভাবছি কারো জন্য কেন এই কাজ: অপারেটর <= হিসাবে ব্যবহারের .set issubset () মেথড একই: docs.python.org/3/library/stdtypes.html#set-types-set-frozenset
edepe

41

বিকল্পগুলির মধ্যে 3 এর জন্য সরল বেঞ্চমার্কিং রিগ।

ডি এবং কিউ এর জন্য আপনার নিজস্ব মান রাখুন


>>> from timeit import Timer
>>> setup='''from random import randint as R;d=dict((str(R(0,1000000)),R(0,1000000)) for i in range(D));q=dict((str(R(0,1000000)),R(0,1000000)) for i in range(Q));print("looking for %s items in %s"%(len(q),len(d)))'''

>>> Timer('set(q) <= set(d)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632499
0.28672504425048828

#This one only works for Python3
>>> Timer('set(q) <= d.keys()','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632084
2.5987625122070312e-05

>>> Timer('all(k in d for k in q)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632219
1.1920928955078125e-05

4
পাইথন 2.7 d.viewkeys()করতে হবে set(q) <= d.viewkeys()
মার্টিজন পিটারস

Python 2.7.5d.keys()পদ্ধতিও আছে
ইভান খারলামভ

3
@ ইভানখারলামভ, তবে পাইথন 2-তে, এটি এমন কোনও বস্তুর সাথে সামঞ্জস্যপূর্ণভাবে ফিরে আসবে নাset(q) <= ...
জন লা রুই

1
আমার খারাপ, আপনি একেবারে স্পট করেছেন: এটি ফিরে আসে TypeError: can only compare to a set। দুঃখিত! :))
ইভান খারলামভ

1
পাইথন 2 অর্ডার পরিবর্তন করুন: d.viewkeys() >= set(q)। অর্ডার কেন গুরুত্ব দেয় তা জানার চেষ্টা করে এখানে এসেছি!
Veedrac

34

আপনাকে কোনও বাম দিকে কোনও সেট মুড়ে রাখতে হবে না। আপনি কেবল এটি করতে পারেন:

if {'foo', 'bar'} <= set(some_dict):
    pass

এটি all(k in d...)সমাধানের চেয়ে আরও ভাল পারফর্ম করে ।


2
এটি সমস্ত (কে ইন ডি ...) সমাধানের চেয়ে আরও ভাল পারফর্ম করে। আমি এটিকে সম্পাদনা হিসাবে পরামর্শ দিয়েছি, তবে কোনও মন্তব্য যুক্ত করা ভাল বলে ভিত্তিতে এটি প্রত্যাখ্যান করা হয়েছিল । সুতরাং এখানে আমি ঠিক সেটাই করছি
चमत्कारিকর্ম

@miraculixx একটি মন্তব্য যুক্ত করা ভাল না। উত্তরের সাথে সম্পর্কিত তথ্য সম্পাদনা করা এবং মন্তব্যগুলি মুছে ফেলা ভাল।
এন্ডোলিথ

1
@ এন্ডোলিথ আমি সম্মত, কিছু লোক অবশ্যই প্রত্যাখ্যানিত সম্পাদনায় দেখতে পাবে যা আমি প্রথম স্থানে করেছি। যাইহোক, এটি এখানে না মেটা জন্য আলোচনা।
অলৌকিক ঘটনা

কেউ দয়া করে এটি ব্যাখ্যা করতে পারেন? আমি একত্রিত করেছি যে {a একটি সেট তৈরি করে, তবে এখানে কম-বা-সমমান অপারেটর কীভাবে কাজ করছে?
লোকেন

1
@ লোকান দি <= অপারেটর পরীক্ষা করে যদি প্রথম সেটটি দ্বিতীয় সেটটির উপসেট হয়। আপনি {'foo', 'বার'}। ইস্যুবসেট (সামডিক্টিক্ট )ও করতে পারেন। সেট পদ্ধতি ডকুমেন্টেশন এখানে পাওয়া যাবে: docs.python.org/2/library/sets.html
মীআও

24

সেট ব্যবহার :

if set(("foo", "bar")).issubset(foo):
    #do stuff

বিকল্পভাবে:

if set(("foo", "bar")) <= set(foo):
    #do stuff

2
সেট (ডি) আমি আমার উত্তরে যেমন ব্যবহার করেছি ঠিক তেমন সেট (ডি.কিজ ()) এর মতো তবে দ্রুত, খাটো, এবং আমি বলব স্টাইলিস্টিকভাবে বেশি পছন্দনীয়।
অ্যালেক্স মার্টেলি

set(d)একই set(d.keys())( যেমনটি অন্তর্বর্তী তালিকা d.keys()তৈরি করে না)
জোছন রিটেল

11

এটি সম্পর্কে:

if all([key in foo for key in ["foo","bar"]]):
    # do stuff
    pass

8
প্রকৃতপক্ষে, কেবল অপ্রয়োজনীয়ই নয়, ইতিবাচকভাবে ক্ষতিকারক, কারণ এগুলির স্বাভাবিক শর্ট সার্কিট আচরণকে বাধা দেয় all
অ্যালেক্স মার্টেলি


9

যদিও আমি অ্যালেক্স মার্তেলির উত্তরটি পছন্দ করি, এটি আমার কাছে পাইথোনিক বলে মনে হয় না। অর্থাৎ, আমি ভেবেছিলাম পাইথোনিক হওয়ার একটি গুরুত্বপূর্ণ অংশটি সহজেই বোধগম্য। এই লক্ষ্য সঙ্গে, <=বুঝতে সহজ নয়।

এটি আরও চরিত্রগুলি থাকা issubset()সত্ত্বেও কার্ল ভয়েগল্যান্ডের উত্তর অনুসারে ব্যবহার করা আরও বোধগম্য। যেহেতু সেই পদ্ধতিটি অভিধান হিসাবে একটি যুক্তি হিসাবে ব্যবহার করতে পারে, একটি সংক্ষিপ্ত, বোধগম্য সমাধান হ'ল:

foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4}

if set(('foo', 'bar')).issubset(foo):
    #do stuff

আমি {'foo', 'bar'}এর জায়গায় ব্যবহার করতে চাই set(('foo', 'bar')), কারণ এটি খাটো। তবে এটি ততটা বোধগম্য নয় এবং আমি মনে করি বন্ধনীগুলি অভিধান হিসাবে খুব সহজেই বিভ্রান্ত হয়।


2
আমি মনে করি এটি বুঝতে সক্ষম হলে আপনি এর অর্থ কী তা বুঝতে পারেন।
বোবোর্ট

এটি প্রতিশব্দ হিসাবে ডকুমেন্টেশনে রয়েছে.issubset() । আমি মনে করি পাইথন ডকুমেন্টেশনে থাকার ফলে এটি ডিফল্টরূপে পাইথোনিক হয়।
ingyhere

4

অ্যালেক্স মার্তেলির সমাধানটি set(queries) <= set(my_dict)সবচেয়ে সংক্ষিপ্ত কোড তবে খুব দ্রুততম নাও হতে পারে। ধরে নিন কিউ = লেন (ক্যোয়ারী) এবং ডি = লেন (আমার_ডিক্ট)।

দুটি সেট তৈরি করতে এটি ও (কিউ) + ও (ডি) লাগে, এবং তারপরে (এক আশা!) কেবলমাত্র ও (মিনিট (কিউ, ডি)) সাবসেট পরীক্ষা করতে হবে - অবশ্যই ধরে নেওয়া যায় যে পাইথন সেট লুক আপ করেছে ও (1) - এটি সবচেয়ে খারাপ ক্ষেত্রে (যখন উত্তরটি সত্য হয়)।

হিউডব্রাউন (এট আল?) এর জেনারেটর সলিউশনটি all(k in my_dict for k in queries)সবচেয়ে খারাপ ক্ষেত্রে (ও ) is

জটিল বিষয়গুলি:
(1) সেট-ভিত্তিক গ্যাজেটের লুপগুলি সি-স্পিডে সম্পন্ন হয় যেখানে যে কোনও-ভিত্তিক গ্যাজেটটি বাইটকোডের উপরে লুপ করে চলেছে।
(২) যে কোনও-ভিত্তিক গ্যাজেটের কলকারী কোয়েরি আইটেমগুলি অর্ডার করতে ব্যর্থতার সম্ভাবনার কোনও জ্ঞান সেই অনুযায়ী ব্যবহার করতে সক্ষম হতে পারে যখন সেট-ভিত্তিক গ্যাজেট এ জাতীয় কোনও নিয়ন্ত্রণের অনুমতি দেয় না।

বরাবরের মতো, যদি গতি গুরুত্বপূর্ণ, অপারেশনাল অবস্থার অধীনে বেঞ্চমার্কিং একটি ভাল ধারণা।


1
আমি চেষ্টা করেছি এমন সমস্ত মামলার জেনারেটর দ্রুত ছিল was stackoverflow.com/questions/1285911/…
জন লা রো

2

আপনি ব্যবহার করতে পারেন ) .issubset ( পাশাপাশি

>>> {"key1", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
True
>>> {"key4", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
False
>>>

1

ল্যাম্বদা ব্যবহার সম্পর্কে কীভাবে?

 if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff

2
এই উত্তরটি কেবলমাত্র কার্যকরী-সঠিক যা পাইথন 1.5 তে একটি সাধারণ পরিবর্তন (গুলি / সত্য / 1 /) দিয়ে কাজ করবে ... তবে এটির জন্য আর কিছুই পাওয়া যায়নি। এবং সত্য জিনিসটি সিকোয়েন্স আর্গের সামনের অংশে চেঁচানো না হয়ে alচ্ছিক আরম্ভকারী আর্গ হিসাবে আরও ভাল হবে।
জন মাচিন

1

আপনি যদি চান:

  • কীগুলির জন্য মানগুলিও পান
  • একাধিক স্বৈরশাসন পরীক্ষা করুন

তারপর:

from operator import itemgetter
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
keys = ("foo","bar") 
getter = itemgetter(*keys) # returns all values
try:
    values = getter(foo)
except KeyError:
    # not both keys exist
    pass

1

এটি এমনটি নয় যা আপনি ভাবেননি, তবে আমি দেখতে পাচ্ছি যে সবচেয়ে সহজ জিনিসটি সাধারণত সেরা:

if ("foo" in foo) and ("bar" in foo):
    # do stuff

1
>>> if 'foo' in foo and 'bar' in foo:
...     print 'yes'
... 
yes

জেসন, () পাইথনে প্রয়োজনীয় নয়।


3
তবুও তারা ভাল স্টাইল হতে পারে ... এগুলি ছাড়াই, আমার সি ++ - অ্যাডেড মস্তিষ্ক সর্বদা বিস্মিত হয় যে এটি "যদি 'foo in (foo এবং' বার ') এর foo হিসাবে ব্যাখ্যা করা যায়:"
জেরেমি ফ্রাইজনার

1
আমি বুঝতে পারি যে এগুলি প্রয়োজনীয় নয়। আমি কেবল অনুভব করি যে তারা এই ক্ষেত্রে স্পষ্টতা যুক্ত করে।
জেসন বেকার

0

কেবল আমার এটি গ্রহণ করুন, দুটি পদ্ধতি রয়েছে যা প্রদত্ত সমস্ত বিকল্পগুলি বোঝা সহজ। সুতরাং আমার প্রধান মানদণ্ডে খুব পঠনযোগ্য কোড রয়েছে, ব্যতিক্রমীভাবে দ্রুত কোড নয়। কোডটি বোধগম্য রাখতে, আমি প্রদত্ত সম্ভাবনাগুলিকে পছন্দ করি:

  • var <= var2.keys ()
  • var.issubset (var2)

"Var <= var2.keys ()" নীচে আমার পরীক্ষায় দ্রুত সম্পাদন করে, আমি এটিকে পছন্দ করি।

import timeit

timeit.timeit('var <= var2.keys()', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"}')
0.1745898080000643

timeit.timeit('var.issubset(var2)', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"};')
0.2644960229999924

0

কেবল কয়েকটি কী কী মেলে কিনা তা নির্ধারণের ক্ষেত্রে এটি কাজ করে:

any_keys_i_seek = ["key1", "key2", "key3"]

if set(my_dict).intersection(any_keys_i_seek):
    # code_here
    pass

কেবলমাত্র কিছু কী মিলছে কিনা তা খুঁজে পাওয়ার জন্য আরও একটি বিকল্প:

any_keys_i_seek = ["key1", "key2", "key3"]

if any_keys_i_seek & my_dict.keys():
    # code_here
    pass

0

সমস্ত কীগুলি ডিকটিতে রয়েছে কিনা তা সনাক্ত করার জন্য অন্য একটি বিকল্প:

dict_to_test = { ... }  # dict
keys_sought = { "key_sought_1", "key_sought_2", "key_sought_3" }  # set

if keys_sought & dict_to_test.keys() == keys_sought: 
    # yes -- dict_to_test contains all keys in keys_sought
    # code_here
    pass

-4
>>> ok
{'five': '5', 'two': '2', 'one': '1'}

>>> if ('two' and 'one' and 'five') in ok:
...   print "cool"
... 
cool

এটি কাজ করে বলে মনে হচ্ছে


এটি বুদ্ধিমান এবং আমি নিশ্চিত হয়েছি যে আমি নিজে চেষ্টা না করা পর্যন্ত এটি কাজ করে না। আমার সন্দেহ হয়েছিল ()যে প্রথমে মূল্যায়ন করা হবে এবং এর ফলাফল Trueহবে, যা কিনা পরে তা পরীক্ষা করে দেখবে True in ok। এটি আসলে কীভাবে কাজ করে ?!
durden2.0

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