【代码】传智播客 Python基础班+就业班

工厂方法模式:基类定义接口,子类具体实现

class Store(object):

	#此处选车并不会执行
	def select_car(self):
		print("Store:select_car")
		
	# 店铺只负责订购功能,添加选车接口
	def order(self, car_type):
		return self.select_car(car_type)

class BMW_Car_Store(Store):
	#继承基类,实现自己的选车方案,即调用工厂类
	def select_car(self, car_type):
		return BMW_Factory().select_car_by_type(car_type)		

class BMW_Factory(object):
	#被调用类的最终选车实现
	def select_car_by_type(self, car_type):
		print("BMW_Factory in BMW_Car_Store")

bmw_store = BMW_Car_Store()
bmw = bmw_store.order("720li")

tcp server

from socket import *
#创建服务器套接字,绑定ip端口,监听(被动连接)数量
svr_skt = socket(AF_INET, SOCK_STREAM)
svr_skt.bind(('',7789))
svr_skt.listen(4)

#创建服务器接收到待客户端(阻塞,等客户端连入),及其ip和port
clt_skt, clt_info = svr_skt.accept()

#接收数据
recv_data = clt_skt.recv(1024)
print str(clt_info)+':'+str(recv_data)

#发送数据,将字符串中文编码
#svr_skt.send('hello xp'.encode('gb2312'))
#此处send数据报错:socket.error: [Errno 32] Broken pipe

#关闭客户端,再服务器
clt_skt.close()
svr_skt.close()

tcp client

from socket import *
#创建套接字,绑定服务器端口
clt_skt = socket(AF_INET, SOCK_STREAM)
clt_skt.connect(('192.168.37.3',8989))
#连接后即发送信息,此处c发给s成功,而s发给c失败
clt_skt.send('hello xp'.encode('gb2312'))
#接收数据
rcv_data = clt_skt.recv(1024)
print(rcv_data)
#关闭套接字
clt_skt.close()

udp receive & send

from socket import *
#创建套接字,绑定接收ip和端口
udp_skt = socket(AF_INET, SOCK_DGRAM)
bind_addr = ('',7788)
udp_skt.bind(bind_addr)
#输入待发送信息,发送
send_info = raw_input('input infomation to send:')
udp_skt.sendto(str(send_info),('192.168.37.3',8080))
#等待接收信息,
recv_data = udp_skt.recvfrom(1024)
print str(recv_data[1])+':'+recv_data[0]
#关闭套接字
udp_skt.close()

创建单例对象
Python 中的单例模式
使用模块, new,装饰器(decorator),元类(metaclass)实现单例模式

class Dog(object):

	#实例创建次数标识,初始化传参标识
	__instance = None
	__init_flag = False
	
	# 只初始化一次对象
	def __init__(self, name):
		if Dog.__init_flag == False:
			self.name = name
			Dog.__init_flag = True

	def __new__(cls, name):
		# 创建单例对象
		if cls.__instance == None:
			cls.__instance = object.__new__(cls)
			return cls.__instance
		else:
			return cls.__instance
			
# 创建第一个
q = Dog("q")
print(q.name)
print(id(q))

# 创建第二个
r = Dog("r")
print(id(q), id(r))
print(q.name, r.name)

老王开枪

# ========gunner shoot=========
class Person(object):
	"""docstring for Person"""
	def __init__(self, name):
		super(Person, self).__init__()
		self.name = name
		self.gun = None 	# storage cite of gun object 存储枪对象引用
		self.power = 100

	def setup_bullet(self, clip, bullet):
		# setup clip with bullets
		clip.save_bullet(bullet)

	def setup_clip(self, gun, clip):
		#setup gun with clip
		gun.save_clip(clip)

	def pick_gun(self, gun):
		#pick up gun
		self.gun = gun

	def shoot(self, target):
		# with gun
		self.gun.fire(target)
		
	def hurted(self, kill_ability):
		self.power -= kill_ability

	def __str__(self):
		# if one has gun, return his power 
		if self.gun:
			return "{0}\'s power is {1}, {2}".format(self.name, self.power, self.gun)
		else:
			if self.power > 0:
				return 	"{0}\'s power is {1}, no gun".format(self.name, self.power)
			else:
				return 	"{0}\'s killed".format(self.name)


class Gun(object):
	"""docstring for Gun"""
	def __init__(self, name):
		super(Gun, self).__init__()
		self.name = name
		self.clip = None
	def save_clip(self, clip):
		self.clip = clip

	def fire(self, target):
		# bullet out from clip 子弹出弹夹
		bullet = self.clip.popup()
		# if has bullet, then hit target 如果弹夹非空,射击敌人
		if bullet:
			bullet.hit(target)
		else:
			print("no bullet")

	def __str__(self):
		if self.clip:
			return "gun info: {0}, {1}".format(self.name, self.clip)
		else:
			return "gun info: {0}, no clip".format(self.name)



class Clip(object):
	"""docstring for Clip"""
	def __init__(self, max_num):
		super(Clip, self).__init__()
		self.max_num = max_num	# max num of clip 弹夹最大容量
		self.bullet_list = []	# storage cite of bullet object 存储子弹对象的引用

	def save_bullet(self, bullet):
		# push bullet into clip # 将子弹压入弹夹
		self.bullet_list.append(bullet)

	def popup(self):
		# clip popup upest bullet, if no bullet, return None  弹夹弹出子弹
		if self.bullet_list:
			return self.bullet_list.pop()
		else:
			return None

	def __str__(self):
		return "clip info: {0}/{1}".format(len(self.bullet_list), self.max_num)


class Bullet(object):
	"""docstring for Bullet"""
	def __init__(self, kill):
		super(Bullet, self).__init__()
		# kill ability 杀伤力
		self.kill = kill
	def hit(self, target):
		# target lose life power value: kill 敌人失去生命力值: 杀伤力
		target.hurted(self.kill)
		
		
def main():
	# 1.gunner 枪手
	gunner = Person("gunner")

	# 2.gun 枪
	ak47 = Gun("ak47")

	# 3.clip 弹夹
	clip = Clip(20)

	# 4.create some bullets 创建一些子弹
	# 	setup clip with these bullets 将这些子弹装入弹夹
	for i in range(10):
		# bullet with kill_ability 子弹,带杀伤力
		bullet = Bullet(10)

		# setup_bullet  装子弹
		gunner.setup_bullet(clip, bullet)

	# 4.setup_clip 装弹夹
	gunner.setup_clip(ak47, clip)

	# 5.pick_gun 拿枪
	gunner.pick_gun(ak47)

	# test clip info 测试信息
	# print(clip)
	# test gun info
	# print(ak47)
	# test gunner object
	print(gunner)	

	# 6.target 敌人
	target = Person("target")
	print(target)

	# 7.shoot_target in 12 times 射击12次
	for i in range(12):
		gunner.shoot(target)
		print(target)
		print(gunner, end="\n\n")

if __name__ == '__main__':
	main()

飞机大战

from pygame.locals import *
import pygame
import time
import random


class Base(object):
    # 抽取坐标,屏幕,图片路径
    def __init__(self, x, y, screen, image):
        self.x = x
        self.y = y
        self.screen = screen
        self.image = pygame.image.load(image)


class BasePlane(Base):
    def __init__(self, x, y, screen, image):
        Base.__init__(self, x, y, screen, image)
        self.bullets = []

    # 抽取飞机对象显示
    def display(self):
        self.screen.blit(self.image, (self.x, self.y))
        # 存储越界子弹,并存储到待删除子弹列表,然后全删掉
        del_bullets = []

        for bullet in self.bullets:
            bullet.display()
            bullet.move()
            if bullet.judge():
                del_bullets.append(bullet)
        for del_bullet in del_bullets:
            self.bullets.remove(del_bullet)


class Plane(BasePlane):
    def __init__(self, screen):
        BasePlane.__init__(self, 230, 600, screen, "./image/qq.jpg")

    def to_left(self):
        self.x -= 20

    def to_right(self):
        self.x += 10

    def fire(self):
        bullet = Bullet(self.screen, self.x, self.y)
        self.bullets.append(bullet)


class Enemy(BasePlane):
    def __init__(self, screen):
        BasePlane.__init__(self, 230, 30, screen, "./image/Icon-114.png")
        self.diret = "left"

    def move(self):
        if self.diret == "left":
            self.x -= 5
        elif self.diret == "right":
            self.x += 5

        if self.x > 400:
            self.diret = "left"
        elif self.x < 20:
            self.diret = "right"
            # break

    def fire(self):
        # 非连续开火

        random_num = random.randint(1, 100)
        if random_num == 2 or random_num == 1:
            bullet_enemy = BulletEnemy(self.screen, self.x, self.y)
            self.bullets.append(bullet_enemy)


class BaseBullet(Base):
    def __init__(self, x, y, screen, image):
        Base.__init__(self, x, y, screen, image)

    def display(self):
        self.screen.blit(self.image, (self.x, self.y))


class Bullet(BaseBullet):
    def __init__(self, screen, x, y):
        BaseBullet.__init__(self, x+12, y-20, screen, "./button_green.9.png")

    def move(self):
        self.y -= 50

    def judge(self):
        if self.y < 100:
            return True
        else:
            return False


class BulletEnemy(BaseBullet):

    def __init__(self, screen, x, y):
        BaseBullet.__init__(self, x+40, y+120, screen, "./button_red.9.png")

    def move(self):
        self.y += 10

    def judge(self):
        if self.y > 500:
            return True
        else:
            return False


def key_ctrl(plane):
    for event in pygame.event.get():
        # 退出
        if event.type == pygame.QUIT:
            print("exit")
            exit(0)
        elif event.type == KEYDOWN:
            if event.key == K_a or event.key == K_LEFT:
                print("left")
                plane.to_left()
            elif event.key == K_d or event.key == K_RIGHT:
                print("right")
                plane.to_right()
            elif event.key == K_SPACE:
                print("space")
                plane.fire()


def main():
    # 创建窗口,背景图片
    screen = pygame.display.set_mode((512, 768), 0, 32)
    bg = pygame.image.load("./image/img_bg_level_1.jpg")
    # 创建飞机,敌机
    plane = Plane(screen)
    enemy = Enemy(screen)

    while True:
        # 显示背景,我机,敌机
        screen.blit(bg, (0, 0))
        plane.display()
        enemy.display()

        # 刷新显示数据到屏幕
        pygame.display.update()

        # 敌机移动,开火
        enemy.move()
        enemy.fire()

        # 控制我机
        key_ctrl(plane)
        time.sleep(0.01)

    # pygame.quit()


if __name__ == '__main__':
    main()

单进程非阻塞tcp server

# tcp_server, one thread, no block
from socket import *
# create socket, reuse port
server_sock = socket(AF_INET, SOCK_STREAM)
server_sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# bind ip, port
local_addr = ('', 7777)
server_sock.bind(local_addr)
# set not block
server_sock.setblocking(False)
# listen socket
server_sock.listen(5)

client_ls = []

while True:
	# waiting new client come
	try:
		client_sock, client_addr = server_sock.accept()
		# BlockingIOError
	except:
		pass
	else:
		print("new client:{0}".format(client_addr))
		# set not block
		client_sock.setblocking(False)
		# storage cite of client info
		client_ls.append((client_sock, client_addr))

	for client_sock, client_addr in client_ls:
		try:
			data = client_sock.recv(1024)
		except:
			pass
		else:
			if len(data) > 0:
				print("{0} : {1}".format(str(client_addr), data.decode('gb2312')))
			else:
				client_sock.close()
				# maybe bug
				client_ls.remove((client_sock, client_addr))
				print("{0} offline".format(client_addr))、

静态文件的Web服务器代码

# coding=utf-8
# static web server
import re
import socket
from multiprocessing import Process
# 定义发送文件根目录
HTML_ROOT_DIR = "./html"


def main():
    tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sock.bind(("", 7777))
    tcp_sock.listen(128)
    tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    while True:
        cli_sock, cli_addr = tcp_sock.accept()
        print("[{0}] 用户已连接...".format(cli_addr))
        cli_process = Process(target=handle_cli, args=(cli_sock,))
        cli_process.start()
        # socket 传入线程后关闭? 不明白
        cli_sock.close()


def handle_cli(cli_sock):
    """handle client requests"""
    # 获取数据,decode为字符串
    request_data = cli_sock.recv(1024).decode("utf-8")
    # print("requested: ", request_data)
    request_lines = request_data.splitlines()
    for line in request_lines:
        print("=======", line)
        
    # 正则解析报文,提取请求文件名 "GET / HTTP/1.1"
    # 下面在第二次网页连入时,IndexError: list index out of range
    response_start_line = request_lines[0]
    file_name = re.match(r"\w+\s+(/[^\s]*)\s", response_start_line).group(1)
	# 设置主页默认文件
    if file_name == "/":
        file_name = "/simple_html.html"

    try:
        with open(HTML_ROOT_DIR + file_name, "rb") as file:
            # 此处decode为字符串,否则浏览器收到数据为字节形式
            file_data = file.read().decode("utf-8")
    except IOError as e:
        # 构造失败响应数据,符合HTTP规范
        response_start_line = "HTTP/1.1 404 not found\r\n"
        response_headers = "Server: My server\r\n"
        response_body = "file not found"

    else:
        # 构造成功响应数据,符合HTTP规范
        response_start_line = "HTTP/1.1 200 OK\r\n"
        response_headers = "Server: My server\r\n"
        response_body = file_data

    response = response_start_line + response_headers + "\r\n" + response_body
    print("response: ", response)
    # 发送响应数据
    cli_sock.send(response.encode("utf-8"))
    # 发送后关闭客户端
    cli_sock.close()


if __name__ == '__main__':
    main()

动态Web服务器,待完善

# coding=utf-8
# dynamic web server
import socket
from multiprocessing import Process
import re
import sys

# 发送文件根目录
HTML_ROOT_DIR = "./html"
WSGI_PYTHON_DIR = "./html"


class HTTPServer(object):

    def __init__(self):
        self.tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    def bind(self, port):
        self.tcp_sock.bind(("", port))

    def start(self):
        self.tcp_sock.listen(128)
        while True:
            cli_sock, cli_addr = self.tcp_sock.accept()
            print("[{0}] 用户已连接...".format(cli_addr))
            cli_process = Process(target=self.handle_cli, args=(cli_sock,))
            cli_process.start()
            # socket 传入线程后关闭? 不明白
            cli_sock.close()

    def start_response(self, status, headers):
        """status = "200 OK"
        headers = [
            ("Content_Type", "text/plain")
        ]
        """
        response_headers = "HTTP/1.1" + status + "\r\n"
        for header in headers:
            response_headers += "%s:%s\r\n" % header
        self.response_headers = response_headers

    def handle_cli(self, cli_sock):
        """handle client requests"""
        # 获取数据,decode为字符串
        request_data = cli_sock.recv(1024).decode("utf-8")
        # print("requested: ", request_data)

        request_lines = request_data.splitlines()
        # for line in request_lines:
            # print("=======", line)
        # 正则解析报文,提取请求
        response_start_line = request_lines[0]
        file_name = re.match(r"\w+\s+(/[^\s]*)\s", response_start_line).group(1)
        method = re.match(r"(\w+)\s+/[^\s]*\s", response_start_line).group(1)
        param = re.match(r"person=(\w+)", response_start_line)#.group(1)
        print(response_start_line)
        print(param)
        env = {
            "PATH_INFO": file_name,
            "METHOD": method,
            "QUERY_STRING": param
        }

        if file_name.endswith(".py"):
            # 处理为动态信息
            # 导入请求模块, 返回值加入返回体
            m = __import__(file_name[1:-3])
            response_body = m.application(env, self.start_response)
            response = self.response_headers + "\r\n" + response_body
        else:
            # 处理为静态信息
            # 第二次请求为页码头的图标,出现异常,这里也归为显示主页
            if file_name == "/" or file_name == "/favicon.ico":
                file_name = "/simple_html.html"
            try:
                with open(HTML_ROOT_DIR + file_name, "rb") as file:
                    # 此处decode为字符串,否则浏览器收到数据为字节形式
                    file_data = file.read().decode("utf-8")
            except IOError as e:
                # 构造失败响应数据,符合HTTP规范
                response_start_line = "HTTP/1.1 404 not found\r\n"
                response_headers = "Server: My server\r\n"
                response_body = "file not found"

            else:
                # 构造成功响应数据,符合HTTP规范
                response_start_line = "HTTP/1.1 200 OK\r\n"
                response_headers = "Server: My server\r\n"
                response_body = file_data

            response = response_start_line + response_headers + "\r\n" + response_body
            # print("response: ", response)
        # 发送响应数据
        cli_sock.send(response.encode("utf-8"))
        # 发送后关闭客户端
        cli_sock.close()


def main():
    sys.path.insert(1, WSGI_PYTHON_DIR)
    http = HTTPServer()
    http.bind(8000)
    http.start()


if __name__ == '__main__':
    main()

列表各方法运行时间测试

import time, timeit

def test1():
	ls = []	
	for i in range(10000):
		ls.append(i)

def test2():
	ls = []
	for i in range(10000):
		ls += [i]

def test3():
	ls =[i for i in range(10000)]

def test4():
	ls = list(range(10000))

def test5():
	ls = []
	for i in range(10000):
		ls.extend([i])

def test6():
	ls = []
	for i in range(10000):
		ls.insert(0, i)

timer1 = timeit.Timer('test1()', 'from __main__ import test1')
timer2 = timeit.Timer('test2()', 'from __main__ import test2')
timer3 = timeit.Timer('test3()', 'from __main__ import test3')
timer4 = timeit.Timer('test4()', 'from __main__ import test4')
timer5 = timeit.Timer('test5()', 'from __main__ import test5')
timer6 = timeit.Timer('test6()', 'from __main__ import test6')

print(timer1.timeit(1000))
print(timer2.timeit(1000))
print(timer3.timeit(1000))
print(timer4.timeit(1000))
print(timer5.timeit(1000))
print(timer6.timeit(1000))

栈,list实现

class Stack(object):
	"""docstring for Stack"""
	def __init__(self):
		self.__ls = []

	def push(self, item):
		self.__ls.append(item)

	def pop(self):
		if self.__ls:
			return self.__ls.pop()
		else:
			return None

	def peek(self):
		if self.__ls:
			return self.__ls[-1]	
		else:
			return None

	def is_empty(self):
		return self.__ls == []

	def size(self):
		return len(self.__ls)


if __name__ == '__main__':
	stack = Stack()
	stack.push(2)
	stack.push(3)
	print(stack.pop())
	print(stack.pop())
	print(stack.pop())

单向链表,删除最复杂。。。

class Node(object):
    """docstring for Node"""

    def __init__(self, elem):
        self.elem = elem
        self.next = None


class SingleLinkList(object):
    """docstring for SingleLinkList"""

    def __init__(self, node=None):
        self._head = node

    def is_empty(self):
        return self._head == None

    def length(self):
        cur = self._head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        cur = self._head
        while cur != None:
            print(cur.elem, end=" ")
            cur = cur.next

    def add(self, item):
        node = Node(item)
        node.next = self._head
        self._head = node

    def append(self, item):
        node = Node(item)
        # 如果为空
        if self.is_empty():
            self._head = node
        else:
            # 如果非空
            cur = self._head
            while cur.next != None:
                cur = cur.next
            cur.next = node

    def insert(self, pos, item):
        node = Node(item)
        # 如果在列表索引范围外,则插入头、尾部
        if pos > self.length()-1:
            self.append(item)
        elif pos > 0:
            cur = self._head
            count = 0
            while count < pos - 1:
                cur = cur.next
                count += 1
            # cur最终指向pos-1位置节点
            node.next = cur.next
            cur.next = node
        else:
            self.add(item)

    def remove(self, item):
        cur = self._head
        pre = None
        while cur != None:
            if cur.elem == item:
                if cur == self._head:
                    self._head = cur.next
                else:
                    pre.next = cur.next
                break
            else:
                pre = cur
                cur = cur.next

    def search(self, item):
        cur = self._head
        count = 0
        while cur != None:
            if cur.elem == item:
                return count
            else:
                count += 1
            cur = cur.next
        return -1


if __name__ == '__main__':
    sll = SingleLinkList()
    # print(sll.is_empty())
    # print(sll.length())
    #
    sll.append(10)
    sll.append(20)
    sll.add(30)
    # sll.add(40)

    # print(sll.length())
    sll.travel()
    sll.remove(30)
    sll.travel()

单向循环链表

class Node(object):
    """docstring for Node"""

    def __init__(self, elem):
        self.elem = elem
        self.next = None


class SingleCycleLinkList(object):
    """docstring for SingleLinkCycleList"""

    def __init__(self, node=None):
        self._head = node
        # 指向头部
        if node:
            node.next = self._head

    def is_empty(self):
        return self._head == None

    def length(self):
        if self.is_empty():
            return 0
        cur = self._head
        count = 1
        while cur.next != self._head:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        if self.is_empty():
            return
        cur = self._head
        while cur.next != self._head:
            print(cur.elem, end=" ")
            cur = cur.next
        # 打印尾结点元素
        print(cur.elem)

    def add(self, item):
        node = Node(item)
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            # cur保存尾结点
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            node.next = self._head
            self._head = node
            # 尾结点重新指向头/node结点
            cur.next = self._head


    def append(self, item):
        node = Node(item)
        # 如果为空
        if self.is_empty():
            self._head = node
            node.next = self._head
        else:
            # 如果非空
            cur = self._head
            while cur.next != self._head:
                cur = cur.next
            node.next = self._head
            cur.next = node

    def insert(self, pos, item):
        node = Node(item)
        # 如果在列表索引范围外,则插入头、尾部
        if pos > self.length()-1:
            self.append(item)
        elif pos > 0:
            cur = self._head
            count = 0
            while count < pos - 1:
                cur = cur.next
                count += 1
            # cur最终指向pos-1位置节点
            node.next = cur.next
            cur.next = node
        else:
            self.add(item)

    def remove(self, item):
        """没有返回值"""
        # 指向头结点和None
        cur = self._head
        pre = None
        while cur.next != self._head:
            if cur.elem == item:
                # 删除头结点的情况
                if cur == self._head:
                    # 寻找尾结点
                    rear = self._head
                    while rear.next != self._head:
                        rear = rear.next
                    self._head = cur.next
                    rear.next = self._head
                # 删除中间结点
                else:
                    pre.next = cur.next
                # 删除掉就返回
                return
            else:
                pre = cur
                cur = cur.next
        # 删除尾结点的情况,此时退出循环,
        # cur指向尾结点,cur.next指向头结点
        if cur.elem == item:
            # 结点只有一个
            if cur == self._head:
                self._head == None
            # 节点数超过一个
            else:
                pre.next = cur.next

    def search(self, item):
        if self.is_empty():
            return -1
        cur = self._head
        count = 0
        while cur.next != self._head:
            if cur.elem == item:
                return count
            else:
                count += 1
            cur = cur.next
        # 判断尾结点
        if cur.elem == item:
            return count
        # 如果不存在
        return -1


if __name__ == '__main__':
    sll = SingleCycleLinkList()
    # print(sll.is_empty())
    # print(sll.length())

    sll.append(10)
    sll.append(20)
    sll.append(30)

    sll.travel()
    sll.remove(10)
    sll.travel()

双向链表

class Node(object):
    """docstring for Node"""
    def __init__(self, elem):
        self.elem = elem
        self.next = None
        self.prev = None


class DoubleLinkList(object):
    """docstring for SingleLinkList"""
    def __init__(self, node=None):
        self._head = node

    def is_empty(self):
        return self._head is None

    def length(self):
        cur = self._head
        count = 0
        while cur:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        cur = self._head
        while cur:
            print(cur.elem, end=" ")
            cur = cur.next

    def add(self, item):
        node = Node(item)
        node.next = self._head
        self._head = node
        node.next.prev = node

    def append(self, item):
        node = Node(item)
        # 如果为空
        if self.is_empty():
            self._head = node
        else:
            # 如果非空
            cur = self._head
            while cur.next:
                cur = cur.next
            cur.next = node
            node.prev = cur

    def insert(self, pos, item):
        # 如果在列表索引范围外,则插入头、尾部
        if pos > self.length()-1:
            self.append(item)
        elif pos > 0:
            cur = self._head
            count = 0
            while count < pos:
                cur = cur.next
                count += 1
            # cur最终指向pos位置节点
            node = Node(item)
            # 先把node节点的前后指针,指向cur前后节点
            # 再打断cur前节点的后指针,指向node
            # 最后打断cur节点的前指针,指向node
            node.next = cur
            node.prev = cur.prev
            cur.prev.next = node
            cur.prev = node
        else:
            self.add(item)

    def remove(self, item):
        cur = self._head
        while cur:
            if cur.elem == item:
                if cur == self._head:
                    self._head = cur.next
                    # 如果链表只有cur一个节点
                    if cur.next:
                        cur.next.prev = None
                else:
                    cur.prev.next = cur.next
                    # 如果cur是链表最后一个节点
                    if cur.next:
                        cur.next.prev = cur.prev
                break
            else:
                cur = cur.next

    def search(self, item):
        cur = self._head
        count = 0
        while cur:
            if cur.elem == item:
                return count
            else:
                count += 1
            cur = cur.next
        return -1


if __name__ == '__main__':
    dll = DoubleLinkList()
    print(dll.is_empty())
    print(dll.length())

    dll.append(10)
    dll.append(20)
    dll.append(30)
    dll.add(0)
    dll.travel()
    dll.remove(0)
    dll.travel()
    print(dll.length())

你可能感兴趣的:(【代码】传智播客 Python基础班+就业班)