මම පයිතන් නියෝග මත 'has_key ()' හෝ 'in' භාවිතා කළ යුතුද?


943

වඩා හොඳ කුමක්දැයි මම කල්පනා කරමි:

d = {'a': 1, 'b': 2}
'a' in d
True

හෝ:

d = {'a': 1, 'b': 2}
d.has_key('a')
True

Answers:


1340

in අනිවාර්යයෙන්ම වඩා පයිතොනික් වේ.

ඇත්ත වශයෙන්ම has_key()පයිතන් 3.x හි ඉවත් කරන ලදි .


3
මීට අමතරව, පයිතන් 3 හි, යතුරු වෙනුවට අගයන්හි පැවැත්ම පරීක්ෂා කිරීමට, d.values ​​() හි >>> 1 උත්සාහ කරන්න
riza

223
වළක්වා ගත හැකි එක් අර්ධ ගොචා එකක් නම් ඔබ එය සිදු කරන බවට වග බලා ගැනීමයි: "some_dict.keys () හි යතුරට වඩා" some_dict හි යතුර ". දෙකම අර්ථාන්විතව සමාන වේ, නමුත් කාර්ය සාධනය අනුව දෙවැන්න වඩා මන්දගාමී වේ (O (n) එදිරිව O (1)). මම දැකලා තියෙනවා මිනිස්සු "in dict.keys ()" කරන්නේ එය වඩාත් පැහැදිලිව පෙනෙන නිසා වඩා හොඳයි කියා.
ඇඩම් පාකින්

2
D ඇඩම්පාර්කින් මම ඔබේ අදහස මගේ පිළිතුර stackoverflow.com/a/41390975/117471
බ un නෝ බ්‍රොනොස්කි

8
D ඇඩම්පාර්කින් පයිතන් 3 හි, keys()පිටපතකට වඩා ශබ්දකෝෂයකට සමාන පෙනුමක් ඇති අතර x in d.keys()ඕ (1) ද වේ. තවමත්, x in dවඩා පයිතොනික් වේ.
ආතර් ටකා

3
D ඇඩම්පාර්කින් සිත්ගන්නා සුළුය, මම එය දුටුවේ නැත. මම හිතන්නේ එය x in d.keys()තාවකාලික වස්තුවක් තැනීම හා විනාශ කිරීම, මතක විබෙදුම සමඟ සම්පුර්ණ x in d.keys()කිරීම, ගණිතමය මෙහෙයුමක් (හැෂ් ගණනය කිරීම) සහ සොයා බැලීමක් සිදු කිරීම ය. d.keys()මෙය තව දුරටත් 10 ගුණයක් පමණ වන බව සලකන්න . මම පරීක්ෂා කර නැති නමුත් මට තවමත් විශ්වාසයි එය ඕ (1) පමණක් බව.
ආතර් ටකා

256

in අලංකාරයෙන් පමණක් නොව (ප්‍රතික්ෂේප නොකෙරේ ;-) පමණක් නොව, කාර්ය සාධනයෙන්ද, උදා:

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop

පහත දැක්වෙන නිරීක්‍ෂණය සැමවිටම සත්‍ය නොවන නමුත් සාමාන්‍යයෙන් , පයිතන්හි වේගවත් විසඳුම වඩාත් අලංකාර සහ පයිතොනික් බව ඔබට පෙනෙනු ඇත ; -mtimeitSO ප්‍රයෝජනවත් වන්නේ එබැවිනි - එය නැනෝ තත්පර සියයක් ඉතිරි කර ගැනීම පමණක් නොවේ ! -)


4
මේ සඳහා ස්තූතියි, “කිසියම්_දෙවියක් තුළ” ඇත්ත වශයෙන්ම ඕ (1) වඩා පහසු බව තහවුරු කර ගැනීම (1999 යැයි පැවසීමට 99 වැඩි කිරීමට උත්සාහ කරන්න, එවිට ධාවන කාලය සමාන බව ඔබට පෙනී යනු ඇත).
ඇඩම් පාකින්

2
has_keyO (1) ද පෙනේ.
dan-gph


42

dict.has_key()ඔබේ කේතය 2.3 ට පෙර ( key in dictහඳුන්වා දුන් විට ) පයිතන් අනුවාදයන් මඟින් ධාවනය කළ යුතු නම් (සහ පමණක් නම්) භාවිතා කරන්න .


1
2013 දී වෙබ්ස්පියර් යාවත්කාලීන කිරීම එහි ප්‍රධාන ස්ක්‍රිප්ටින් භාෂාව ලෙස ජයිතන් 2.1 භාවිතා කරයි. එබැවින් මෙය සටහන් කර වසර පහකට පසුව අවාසනාවකට මෙය තවමත් ප්‍රයෝජනවත් කරුණකි.
ArtOfWarfare

23

inඔබේ ක්‍රියාකාරිත්වය සැබවින්ම විනාශ කරන එක් උදාහරණයක් තිබේ .

ඔබ භාවිතා කරන්නේ නම් inඑය සාමාන්ය මත (1) උපකරණ පමණක් බව රුවනයකි __getitem__හා has_key()නමුත් __contains__ඔබ සාමාන්ය හැරී ඇත (1) O (N) බවට සොයන්න (ලෙස සොයා inආපසු හරහා රේඛීය සෝදිසි වැටෙන __getitem__).

නිවැරදි කිරීම ඉතා සුළුය:

def __contains__(self, x):
    return self.has_key(x)

6
මෙම පිළිතුර පළ කරන විට අදාළ වූ නමුත් 99.95% පා readers කයන්ට එය නොසලකා හැරිය හැකිය. දී බොහෝ අවස්ථා වලදී, ඔබ මෙම වසං, ඔබ එය දන්නේ කරන්නම් දෙයක් සමග වැඩ කරන්නේ නම්.
wizzwizz4

2
මෙය ඇත්ත වශයෙන්ම ප්‍රශ්නයක් නොවේ. has_key()වන Python 2 ශබ්ද කෝෂ විශේෂිත . in/ __contains__භාවිතා කිරීමට නිවැරදි API; සම්පුර්ණ ස්කෑන් කිරීම වැළැක්විය නොහැකි බහාලුම් සඳහා කෙසේ හෝhas_key() ක්‍රමයක් නොමැත , සහ O (1) ප්‍රවේශයක් තිබේ නම් එය භාවිතයට විශේෂිත වූවක් වන අතර ගැටළුව සඳහා නිවැරදි දත්ත වර්ගය තෝරා ගැනීමට සංවර්ධකයාට වේ.
මාර්ටිජන් පීටර්ස්

17

Dict.has_key () සඳහා වූ විසඳුම ඉවත් කර ඇත, 'in' භාවිතා කරන්න - උත්කෘෂ්ට පෙළ සංස්කාරක 3

මෙන්න මම 'වයස්' නම් ශබ්ද කෝෂයේ උදාහරණයක් ගෙන ඇත -

ages = {}

# Add a couple of names to the dictionary
ages['Sue'] = 23

ages['Peter'] = 19

ages['Andrew'] = 78

ages['Karren'] = 45

# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:

    print "Sue is in the dictionary. She is", ages['Sue'], "years old"

else:

    print "Sue is not in the dictionary"

6
නිවැරදි, නමුත් එයට දැනටමත් පිළිතුරු ලැබී ඇත, ස්ටැකෝව්ෆ්ලෝ වෙත සාදරයෙන් පිළිගනිමු, උදාහරණයට ස්තූතියි, සෑම විටම පිළිතුරු පරීක්ෂා කරන්න!
igorgue

@igorgue මට ඇය කෙරෙහි ඇති අඩුපාඩු ගැන විශ්වාස නැත. ඇගේ පිළිතුර දැනටමත් පිළිතුරු දී ඇති පිළිතුරට සමාන විය හැකි නමුත් ඇය උදාහරණයක් සපයයි. SO හි පිළිතුරක් වීමට එය ප්‍රමාණවත් නොවේද?
අක්ෂට් අගර්වාල්

15

has_keyශබ්ද කෝෂ ක්‍රමයක් වන නමුත් inඕනෑම එකතුවක් මත ක්‍රියා කරනු ඇති අතර, නැති වූ විට පවා __contains__, inසොයා ගැනීම සඳහා එකතුව නැවත සැකසීමට වෙනත් ක්‍රමයක් භාවිතා කරනු ඇත.


1
තවද "x in xrange (90, 200) <=> 90 <= x <200"
u0b34a0f6ae

1
…: මෙය ඉතා නරක අදහසක් සේ පෙනේ: 2 වෙනුවට මෙහෙයුම් 50 ක්
ක්ලෙමන්ට්

1
@ ක්ලෙමන්ට් පයිතන් 3 හි, ඇත්ත වශයෙන්ම වස්තූන් inපිළිබඳ පරීක්ෂණ සිදු කිරීම තරමක් කාර්යක්ෂම වේ range. පයිතන් 2 xrangeහි එහි කාර්යක්ෂමතාව ගැන මට එතරම් විශ්වාසයක් නැත . ;)
PM 2Ring

@ ක්ලෙමන්ට් පයිතන් 3 හි නොමැත; අගයක් පරාසය තුළ තිබේද නැද්ද යන්න සුළු වශයෙන් ගණනය__contains__ කළ හැකිය .
මාර්ටිජන් පීටර්ස්

1
Lex ඇලෙක්සැන්ඩ්‍රෙහුවාට් ඔබේ වේලාවට rangeසෑම අවස්ථාවකම නව අවස්ථාවක් නිර්මාණය කිරීමේ පොදු කාර්ය ඇතුළත් වේ . කලින් පැවති තනි අවස්ථාවක් භාවිතා කරමින් “කාල පරාසය තුළ පූර්ණ සංඛ්‍යා” පරීක්ෂණය මගේ වේලාවන්හි 40% ක් පමණ වේගවත් වේ.
මිස්ටර්මියාගි

15

ඇඩම් පාකින්ගේ අදහස් දැක්වීම් සමඟ ඇලෙක්ස් මාටෙලිගේ කාර්ය සාධන පරීක්ෂණ පුළුල් කිරීම ...

$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
    x = t.timeit(number)
  File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
    d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(  99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop

$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(  99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop

$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop

පුදුමාකාර සංඛ්‍යාලේඛන, සමහර විට ව්‍යංගයෙන් පැහැදිලි වීමට වඩා හොඳ විය හැකිය (අවම වශයෙන් කාර්යක්ෂමතාවයෙන්) ...
varun

ස්තූතියි, වරුන්. මට මෙම පිළිතුර අමතක වී තිබුණි. මට මෙවැනි පරීක්ෂණ නිතර නිතර කළ යුතුයි. දේවල් කිරීමට මිනිසුන් හොඳම මාර්ගය ගැන තර්ක කරන දිගු කෙඳි මම නිතරම කියවමි . නමුත් සාක්ෂි ලබා ගැනීම කොතරම් පහසුදැයි මට මතක නැත .
බ un නෝ බ්‍රොනොස්කි

මෙම අත්හදා බැලීමේ අඩුපාඩුවක් ඇත, එය ප්‍රධාන සෙවීමේ වේලාව සමඟ ඩික් නිර්මාණය කිරීමේ කාලය මිශ්‍ර කළේය. යතුරු සෙවීම සඳහා පමණක් වැය කරන කාලය මැනීම සඳහා මේ දෙක වෙන් කිරීම වඩා හොඳය. ඔබ මේ දෙක වෙන් කළ පසු, කාල ප්‍රති result ලය මඟින් 'ඩී යතුර' සහ ඩී. කේස් () හි යතුර යන දෙකම ඕ (1) ලෙස පෙනේ. අත්යවශ්ය වෙනසක් නැත, D.keys () හි යතුර D හි යතුරට වඩා ටිකක් මන්දගාමී වුවද එය O (N) එදිරිව O (1) නොවේ.
ජල ගල

මම පයිතන් 3 භාවිතා කළෙමි, එබැවින් මගේ නිගමනය වූයේ පයිතන් 3 සඳහා ය (පයිතන් 2 හි එය ඕ (එන්) එදිරිව ඕ (1) විය හැකි නමුත් මම මෙය පයිතන් 3 හි දුටුවේ නැත.
ජල ගල

-2

ඔබට මේ වගේ දෙයක් තිබේ නම්:

t.has_key(ew)

පයිතන් 3.X සහ ඊට ඉහළින් ධාවනය කිරීම සඳහා එය පහළට වෙනස් කරන්න:

key = ew
if key not in t

7
නැත, ඔබ පරීක්ෂණය පෙරළා දැමීය. අගය යොමු කිරීම් ද ශබ්ද කෝෂයේ යතුරක් නම් t.has_key(ew)ආපසු එයි . අගය ශබ්ද කෝෂයේ නොමැති නම් නැවත පැමිණේ . එපමණක්ද නොව, අන්වර්ථය ඉතා අතිරික්ත වේ. නිවැරදි අක්ෂර වින්‍යාසය . මීට වසර 8 කට පෙර පිළිගත් පිළිතුර මෙයයි. Trueewkey not in tTruekey = ewif ew in t
මාර්ටිජන් පීටර්ස්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.