"dict" nesnesinin "has_key" özniteliği yok


114

Python'da bir grafiği dolaşırken, a Bu hatayı alıyorum:

"dict" nesnesinin "has_key" özniteliği yok

İşte kodum:

def find_path(graph, start, end, path=[]):
    path = path + [start]
    if start == end:
        return path
    if not graph.has_key(start):
        return None
    for node in graph[start]:
        if node not in path:
            newpath = find_path(graph, node, end, path)
            if newpath: return newpath
    return None

Kod, bir düğümden diğerine giden yolları bulmayı amaçlar. Kod kaynağı: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

Neden bu hatayı alıyorum ve bunu nasıl düzeltebilirim?


2
if not start in graph:
Peter Ahşap

Yanıtlar:


189

has_keyPython 3'te kaldırıldı. Belgelerden :

  • Kaldırıldı dict.has_key()- inbunun yerine operatörü kullanın.

İşte bir örnek:

if start not in graph:
    return None

1
Sanırım key not in d.keys()muhtemelen çok daha yavaş, çünkü key not in dO (1) araması olmalı ve keysO (n) araması olan bir liste oluşturduğuna inanıyorum (hafızada fazladan yer almaktan bahsetmiyorum bile). Bu konuda yanılıyor olabilirim - yine de karıştırılmış arama olabilir
Adam Smith

3
Python 3'te olmayan @AdamSmith d.keys(), set arayüzünün çoğunu uygulayan bir görünümdür.
Antti Haapala

3
Kaldırıldı ... ama neden? Python 2 portunu python 3'e daha fazla iş yaptığından beri.
Meyve

1
@ 林果 皞: Yeni bir ana sürümün tüm amacı, geliştiricilerin, dil olgunlaştıkça eski özellikleri desteklemek zorunda kalmadan değişiklikleri kırmayı da içeren iyileştirmeler sunabilmesidir. Bu her zaman yeni bir ana sürüme yükseltmeden önce dikkate alınması gereken bir risktir. Bu durumda, indaha kısa ve daha Pythonic, aynı zamanda dildeki diğer koleksiyonlarla uyumludur.
johnnyRose

23

has_key , Python 3.0'da kullanımdan kaldırılmıştır . Alternatif olarak 'in' kullanabilirsiniz

graph={'A':['B','C'],
   'B':['C','D']}

print('A' in graph)
>> True

print('E' in graph)
>> False

20

Python3'te, has_key(key)ile değiştirilir__contains__(key)

Python3.7'de test edilmiştir:

a = {'a':1, 'b':2, 'c':3}
print(a.__contains__('a'))

5

Sanırım, inbir anahtarın zaten var olup olmadığını belirlerken kullanılmasının "daha pitonik" olarak kabul edildiğini düşünüyorum .

if start not in graph:
    return None

The Zen of Python'a (PEP 20) göre, emin değilim: "Açık, örtük olmaktan iyidir". inAnahtar kelimeyi kullanırsanız, niyetinizin yeterince açık olmayabileceğini düşünüyorum, ne anlama if start not in graph:geliyor? olabilir graphbir liste ve It kontrolleri listesinde böyle bir dize varsa nedir? Öte yandan, sizin gibi sözdizimi kullanırsanız has_key(şimdi kaldırıldı) ya da en azından in graph.keys()daha net olduğunu graphbir olduğunudict
Amitay Davulcu

4

Belgedeki kodun tamamı şöyle olacaktır:

graph = {'A': ['B', 'C'],
             'B': ['C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F'],
             'F': ['C']}
def find_path(graph, start, end, path=[]):
        path = path + [start]
        if start == end:
            return path
        if start not in graph:
            return None
        for node in graph[start]:
            if node not in path:
                newpath = find_path(graph, node, end, path)
                if newpath: return newpath
        return None

Yazdıktan sonra belgeyi kaydedin ve F 5 tuşuna basın

Bundan sonra, Python IDLE kabuğunda çalıştıracağınız kod şöyle olacaktır:

find_path (grafik, 'A', 'D')

IDLE'de almanız gereken cevap şudur:

['A', 'B', 'C', 'D'] 

Lütfen bunu açıklayabilir misiniz? Özellikle özyineleme kısmı.
Encipher

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.