Python Linked List
上周日教导一个科班非技术的朋友学习 Python 编程。他的 Python 水平大概就是看了几篇短的 Python 介绍博客、会流程控制和全局函数编写。
具体教导思路是从自己实现一个链表出发,研究学习 Python 数据结构、接口、算法的实现和运用、然后:
0. 学会画图表达对象之间的关联、数据结构的操作、并实现它。
- 慢慢用 Python 的特性去优化链表、学习 Python 特性与最佳实践;
- 刷 Leetcode 链表题目、锻炼思维;
- 熟悉之后、在进行二叉排序树的 0、1、2。
昨天算是实现了一个带遍历、插入、删除的 LinkedList。但是写的很长、大概用到的“新”特性只有 Python 的类。
今天打算让他快速前进,尝试拔苗助长ing:
- 理解成员函数的self、了解函数的默认参数;
- 理解抛出异常的代码写法和运行现象;
- 还有再学习一下类的特殊方法
__len__
和__str__
; - 理解鸭子类型:
- Python 有个逻辑:不管你是什么动物,会嘎嘎叫的就是鸭子;
- 你想想看 ListLink.head 和 Node.next 是不是一个东西?
- 可不可以起成同一个名字 把它当成嘎嘎叫方法 (next),从而简化我们的代码;
- 如果把 ListLink 当作鸭子类,那么Node也是一个鸭子类;
- 关键:Node 和 ListLink 一样,也有 next 属性;两者的 next 属性的性质一样,要么是 None,要么是一个有 data 有 next 的对象;
- 另一种理解:链表第一个结点之后的部分还是一个完整的链表。
- 理解函数是一等公民 -- 下面代码还没实现、因为已经有
__iter__
了没有必要了。
个人感觉4讲早了,但是看他写的又长又臭,忍不住不教。
代码:
class Stack:
class Node:
def __init__(self, data, next = None):
self.data = data
self.next = next
def __init__(self):
self.next = None
def push(self, data = None, index = 0):
if index < 0 or index > len(self):
raise IndexError("Given index is invalid.")
cur = self
for i in range(index):
cur = cur.next
cur.next = Node(data, cur.next)
def pop(self, index = 0):
if index < 0 or index >= len(self):
raise IndexError("Given index is invalid.")
cur = self
for i in range(index):
cur = cur.next
retval = cur.next.data
cur.next = cur.next.next
return retval
def __iter__(self):
cur = self
while cur.next is not None:
yield cur.next.data
cur = cur.next
def __len__(self):
len = 0
cur = self
while cur.next is not None:
len = len + 1
cur = cur.next
return len
def __str__(self):
cur = self
if cur.next is None:
return "[]"
st = "["
while cur.next.next is not None:
st = st + str(cur.next.data) + ", "
cur = cur.next
st = st + str(cur.next.data) + "]"
return st
测试:
s = Stack()
print(s)
s.push(1)
print(s)
s.push(0.5)
print(s)
s.push(1.5, 1)
print(s)
s.push(2, 3)
print(s)
print(s.pop())
print(s)
print(s.pop(2))
print(s)
输出:
[]
[1]
[0.5, 1]
[0.5, 1.5, 1]
[0.5, 1.5, 1, 2]
0.5
[1.5, 1, 2]
2
[1.5, 1]