python队列和具名元组

  • python的四种队列

    • 先进先出队列Queue

    • 后进先出队列LifoQueue

    • 优先级队列PriorityQueue

    • 双边队列deque

      前三种的导入方式是from queue import Queue, LifoQueue, PriorityQueue

      三者的方式也是极其相似:

      队列元素添加obj.put()、队列元素删除obj.get(),这里的删除是先返回数据再删除元素

      先进先出和后进先出队列的上述两个方法都是根据队列的特点定义的功能

      优先级队列元素添加时是一个元组,元组中有两个值,第一个表示优先级,第二个表示对象(值)

      from queue import Queue, LifoQueue, PriorityQueue
      q = Queue(maxsize=0)
      lq = LifoQueue(maxsize=0)
      pq = PriorityQueue(maxsize=0)
      for i in range(5):
          q.put(i)
          lq.put(i)
          pq.put((str(i), i))
      print(q, lq, pq)
      for i in range(5):
          print(q.get(), lq.get(), pq.get())
       

      最后一张导入方式是from collections import deque

      队列元素添加方式有两种,在左边添加obj.appendleft(),在右边添加obj.append()

      队列元素删除方式有两种,从左边删除obj.popleft(),从右边删除obj.pop()

      队列元素添加的另一种方式:添加一个列表,extend(values),extendleft(reversed(values)),values是一个可迭代对象,extendleft添加时会将values反转顺序

      from collections import deque
      values = ["a", "b"]
      dq = deque(values)  # values必须是一个可迭代对象,如果values是一个字典,默认存储的是字典的键
      dq.appendleft("c")
      print(dq, dq.pop(), dq)
      dq.append("d")
      print(dq, dq.popleft(), dq)
  • python的具名元组和类

    • 其实和类很相似,以下具体讲解具名元组的用法

    • 导包方式:from collections import namedtuple

    • namedtuple格式:namedtuple(type_name, field_names, rename=False, verbose=False)

      • type_name:就是一个类型的名称,可以理解为类名(但不是类名,他们很相似而已)

      • field_names:可以是列表形式表示属性,可以是字符串用空格隔开表示多个属性

      • rename和verbose默认即可

    • namedtuple属性和方法:

      • _fields:列出当前实例的所有属性

      • _make():接受一个列表,列表中的元素是实例属性对应的值

      • _asdict():就是将实例属性和值类似这样的形式存储

      • 上述结果: OrderedDict([('name', 'Runoob'), ('sex', 'male'), ('age', 22)])

      from collections import namedtuple
      User = namedtuple("User", "name age gender")   # 相当于定义好一个类了
      user1 = User("huxiansen", 18, "male")
      print(user1)
  • 根据双边队列和具名元组实现深度优先搜索的最短路径

    from collections import deque
    from collections import namedtuple
    ​
    ​
    def dfs(start_node, end_node, graph):     # 基于深度优先搜索的最短路径的实现
        node = namedtuple("node", "name from_node")   # 定义节点的结构
        search_deque = deque()  # 存储访问的节点
        visited = {}  # 存储当前路径已访问过的节点
        road = {}  # 存储完整路径及当前路径的长度
    ​
        search_deque.append(node(start_node, None))  # 存储所有路径开始的起点
        path = []    # 用户回溯的路径
    while search_deque:
            current_node = search_deque.popleft()
            if current_node.name not in visited:
                if current_node.name != end_node:
                    visited[current_node.name] = current_node  # 如果没有找到目标节点,将节点设为已访问,并将相邻节点加入搜索队列中
                    for node_name in reversed(graph[current_node.name]):
                        search_deque.appendleft(node(node_name, current_node.name))    # 基于深度优先搜索添加队列的核心
                else:  # 找到起点到终点的路径,存储完整路径和路径长度
                    pre_node = current_node  # 路径回溯的关键在于每个节点中存储的前置节点
                    while True:
                        if pre_node.name == start_node:
                            path.append(start_node)
                            road[str(path[::-1])] = len(path) - 1  # 存储完整路径和当前路径的长度
                            path.clear()  # 路径清空
                            break
                        else:
                            path.append(pre_node.name)
                            pre_node = visited[pre_node.from_node]  # 取出前置节点的前置节点
        print("完整路径集:", road)
        
    ​
    if __name__ == "__main__":
        graph = dict()
        graph[1] = [2, 3]
        graph[2] = [5]
        graph[3] = [4, 7]
        graph[4] = [8]
        graph[5] = [6]
        graph[6] = []
        graph[7] = [8]
        graph[8] = []
        dfs(1, 8, graph)
  • 根据双边队列和具名元组实现深度优先搜索的带有权值的最短路径

    from collections import deque
    from collections import namedtuple
    ​
    ​
    def dfs(start_node, end_node, graph):     # 基于深度优先搜索的最短路径的实现
        node = namedtuple("node", "name count from_node")   # 定义节点的结构,count表示到达当前节点的值
        search_deque = deque()  # 存储访问的节点
        visited = {}  # 存储当前路径已访问过的节点
        road = {}  # 存储完整路径及当前路径的长度
    ​
        search_deque.append(node(start_node, 0, None))  # 存储所有路径开始的起点
        path = []    # 回溯的路径
        path_count = 0   # 回溯的路径的权值
    while search_deque:
            current_node = search_deque.popleft()
            # 由于搜寻最短路径可能会返回上一节点,所以这里不再判断节点是不是被访问过了
            if current_node.name != end_node:
                visited[current_node.name] = current_node  # 如果没有找到目标节点,将节点设为已访问,并将相邻节点加入搜索队列中
                for node_name in reversed(list(graph[current_node.name].keys())):
                    if graph[current_node.name][node_name] != 0:
                        # 基于深度优先搜索添加队列的核心
                        search_deque.appendleft(node(node_name, graph[current_node.name][node_name], current_node.name))
            else:  # 找到起点到终点的路径,存储完整路径和路径长度
                pre_node = current_node  # 路径回溯的关键在于每个节点中存储的前置节点
                while True:
                    if pre_node.name == start_node:
                        path.append(start_node)
                        path_count += pre_node.count
                        road[str(path[::-1])] = path_count  # 存储完整路径和当前路径的权值和
                        path.clear()  # 路径清空
                        path_count = 0  # 路径权值置为0
                        break
                    else:
                        path.append(pre_node.name)
                        path_count += pre_node.count
                        pre_node = visited[pre_node.from_node]  # 取出前置节点的前置节点
        print("加权有向图完整路径集:", road)
        # 到达某顶点的带有加权的最短路径及权值
        print(min(road, key=lambda k: road[k]), road[min(road, key=lambda k: road[k])])
    ​
    ​
    if __name__ == '__main__':
        graph = {   # 字典存储加权有向图信息
            1: {1: 0, 2: 10, 3: 0, 4: 30, 5: 100},
            2: {1: 0, 2: 0, 3: 50, 4: 0, 5: 0},
            3: {1: 0, 2: 0, 3: 0, 4: 0, 5: 10},
            4: {1: 0, 2: 0, 3: 20, 4: 0, 5: 60},
            5: {1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
        }
        for i in range(2, 6):
            dfs(1, i, graph)
    ​

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值