วัตถุ "dict" ไม่มีแอตทริบิวต์ "has_key"


114

ในขณะที่สำรวจกราฟใน Python ฉันได้รับข้อผิดพลาดนี้:

วัตถุ "dict" ไม่มีแอตทริบิวต์ "has_key"

นี่คือรหัสของฉัน:

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

รหัสนี้มีจุดมุ่งหมายเพื่อค้นหาเส้นทางจากโหนดหนึ่งไปยังอีกโหนดหนึ่ง แหล่งที่มาของรหัส: http://cs.mwsu.edu/~terry/courses/4883/lectures/graphs.html

เหตุใดฉันจึงได้รับข้อผิดพลาดนี้และฉันจะแก้ไขได้อย่างไร


2
if not start in graph:
Peter Wood

1
อาจซ้ำกันของ'has_key ()' หรือ 'in'?
Peter Wood

คำตอบ:


189

has_keyถูกลบออกใน Python 3 จากเอกสาร :

  • ลบออกdict.has_key()- ใช้ตัวinดำเนินการแทน

นี่คือตัวอย่าง:

if start not in graph:
    return None

1
ผมคิดว่าkey not in d.keys()น่าจะเป็นมากช้าเกินไปเนื่องจากkey not in dควรจะ O (1) การค้นหาและผมเชื่อว่าkeysผลิตรายการซึ่งเป็น O (n) ค้นหา (ไม่พูดถึงการใช้พื้นที่ในหน่วยความจำเสริม) ฉันอาจจะผิดเกี่ยวกับเรื่องนี้ - อาจยังคงมีการค้นหาที่แฮช
Adam Smith

3
@AdamSmith ไม่ได้อยู่ใน Python 3 d.keys()เป็นมุมมองที่ใช้ส่วนต่อประสานชุดส่วนใหญ่
Antti Haapala

3
มันลบออก ... แต่ทำไม? เนื่องจากมันทำให้พอร์ต python 2 เป็น python 3 ทำงานได้มากขึ้น
ผลไม้

1
@ 林果皞: จุดรวมของเวอร์ชันหลักใหม่คือนักพัฒนาสามารถแนะนำการปรับปรุงซึ่งอาจรวมถึงการเปลี่ยนแปลงที่ไม่สมบูรณ์แทนที่จะต้องรองรับฟีเจอร์เก่าเมื่อภาษาครบกำหนด นี่เป็นความเสี่ยงที่ต้องพิจารณาก่อนอัปเกรดเป็นเวอร์ชันหลักใหม่เสมอ ในกรณีนี้inจะสั้นกว่าและ Pythonic มากกว่ารวมทั้งสอดคล้องกับคอลเล็กชันอื่น ๆ ในภาษา
johnnyRose

23

has_keyได้รับการคัดค้านในPython 3.0 หรือคุณสามารถใช้'in'

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

print('A' in graph)
>> True

print('E' in graph)
>> False

20

ใน python3 has_key(key)จะถูกแทนที่ด้วย__contains__(key)

ทดสอบใน python3.7:

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

5

ฉันคิดว่ามันถือว่าเป็น "pythonic มากกว่า" ที่จะใช้inเมื่อพิจารณาว่ามีคีย์อยู่แล้วหรือไม่เช่นใน

if start not in graph:
    return None

ฉันไม่แน่ใจตาม The Zen of Python (PEP 20): "Explicit is better than implicit" ฉันคิดว่าหากคุณใช้inคีย์เวิร์ดความตั้งใจของคุณอาจไม่ชัดเจนเพียงพอว่าif start not in graph:หมายถึงอะไร? อาจgraphเป็นรายการและตรวจสอบว่าไม่มีสตริงดังกล่าวในรายการหรือไม่? ในทางกลับกันถ้าคุณใช้ไวยากรณ์เช่นhas_key(เลิกใช้แล้วตอนนี้) หรืออย่างน้อยin graph.keys()ก็ชัดเจนมากขึ้นนั่นgraphคือ adict
Amitay Drummer

4

รหัสทั้งหมดในเอกสารจะเป็น:

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

หลังจากเขียนเสร็จแล้วให้บันทึกเอกสารแล้วกด F 5

หลังจากนั้นรหัสที่คุณจะเรียกใช้ใน Python IDLE shell จะเป็น:

find_path (กราฟ 'A', 'D')

คำตอบที่คุณควรได้รับใน IDLE คือ

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

คุณช่วยอธิบายได้ไหมโดยเฉพาะส่วนการเรียกซ้ำ
Encipher

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.