零基础入门学习Python第二阶01生成式(推导式),数据结构

Python语言进阶

重要知识点

  • 生成式(推导式)的用法
  prices = {'AAPL': 191.88,'GOOG': 1186.96,'IBM': 149.24,'ORCL': 48.44,'ACN': 166.89,'FB': 208.09,'SYMC': 21.29}# 用股票价格大于100元的股票构造一个新的字典prices2 = {key: value for key, value in prices.items() if value > 100}print(prices2)

说明:生成式(推导式)可以用来生成列表、集合和字典。

  • 嵌套的列表的坑
  names = ['关羽', '张飞', '赵云', '马超', '黄忠']courses = ['语文', '数学', '英语']# 录入五个学生三门课程的成绩# scores = [[None] * len(courses)] * len(names)scores = [[None] * len(courses) for _ in range(len(names))]for row, name in enumerate(names):for col, course in enumerate(courses):scores[row][col] = float(input(f'请输入{name}{course}成绩: '))print(scores)
  • heapq模块(堆排序)
  """从列表中找出最大的或最小的N个元素堆结构(大根堆/小根堆)"""import heapqlist1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92]list2 = [{'name': 'IBM', 'shares': 100, 'price': 91.1},{'name': 'AAPL', 'shares': 50, 'price': 543.22},{'name': 'FB', 'shares': 200, 'price': 21.09},{'name': 'HPQ', 'shares': 35, 'price': 31.75},{'name': 'YHOO', 'shares': 45, 'price': 16.35},{'name': 'ACME', 'shares': 75, 'price': 115.65}]print(heapq.nlargest(3, list1))print(heapq.nsmallest(3, list1))print(heapq.nlargest(2, list2, key=lambda x: x['price']))print(heapq.nlargest(2, list2, key=lambda x: x['shares']))
  • itertools模块
  """迭代工具模块"""import itertools# 产生ABCD的全排列itertools.permutations('ABCD')# 产生ABCDE的五选三组合itertools.combinations('ABCDE', 3)# 产生ABCD和123的笛卡尔积itertools.product('ABCD', '123')# 产生ABC的无限循环序列itertools.cycle(('A', 'B', 'C'))
  • collections模块

    常用的工具类:

    • namedtuple:命令元组,它是一个类工厂,接受类型的名称和属性列表来创建一个类。
    • deque:双端队列,是列表的替代实现。Python中的列表底层是基于数组来实现的,而deque底层是双向链表,因此当你需要在头尾添加和删除元素时,deque会表现出更好的性能,渐近时间复杂度为 O ( 1 ) O(1) O(1)
    • Counterdict的子类,键是元素,值是元素的计数,它的most_common()方法可以帮助我们获取出现频率最高的元素。Counterdict的继承关系我认为是值得商榷的,按照CARP原则,Counterdict的关系应该设计为关联关系更为合理。
    • OrderedDictdict的子类,它记录了键值对插入的顺序,看起来既有字典的行为,也有链表的行为。
    • defaultdict:类似于字典类型,但是可以通过默认的工厂函数来获得键对应的默认值,相比字典中的setdefault()方法,这种做法更加高效。
  """找出序列中出现次数最多的元素"""from collections import Counterwords = ['look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes','the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around','the', 'eyes', "don't", 'look', 'around', 'the', 'eyes','look', 'into', 'my', 'eyes', "you're", 'under']counter = Counter(words)print(counter.most_common(3))

数据结构和算法

  • 算法:解决问题的方法和步骤

  • 评价算法的好坏:渐近时间复杂度和渐近空间复杂度。
    在这里插入图片描述

在这里插入图片描述

  • 排序算法(选择、冒泡和归并)和查找算法(顺序和折半)
  def select_sort(items, comp=lambda x, y: x < y):"""简单选择排序"""items = items[:]for i in range(len(items) - 1):min_index = ifor j in range(i + 1, len(items)):if comp(items[j], items[min_index]):min_index = jitems[i], items[min_index] = items[min_index], items[i]return items
  def bubble_sort(items, comp=lambda x, y: x > y):"""冒泡排序"""items = items[:]for i in range(len(items) - 1):swapped = Falsefor j in range(len(items) - 1 - i):if comp(items[j], items[j + 1]):items[j], items[j + 1] = items[j + 1], items[j]swapped = Trueif not swapped:breakreturn items
  def bubble_sort(items, comp=lambda x, y: x > y):"""搅拌排序(冒泡排序升级版)"""items = items[:]for i in range(len(items) - 1):swapped = Falsefor j in range(len(items) - 1 - i):if comp(items[j], items[j + 1]):items[j], items[j + 1] = items[j + 1], items[j]swapped = Trueif swapped:swapped = Falsefor j in range(len(items) - 2 - i, i, -1):if comp(items[j - 1], items[j]):items[j], items[j - 1] = items[j - 1], items[j]swapped = Trueif not swapped:breakreturn items
  def merge(items1, items2, comp=lambda x, y: x < y):"""合并(将两个有序的列表合并成一个有序的列表)"""items = []index1, index2 = 0, 0while index1 < len(items1) and index2 < len(items2):if comp(items1[index1], items2[index2]):items.append(items1[index1])index1 += 1else:items.append(items2[index2])index2 += 1items += items1[index1:]items += items2[index2:]return itemsdef merge_sort(items, comp=lambda x, y: x < y):return _merge_sort(list(items), comp)def _merge_sort(items, comp):"""归并排序"""if len(items) < 2:return itemsmid = len(items) // 2left = _merge_sort(items[:mid], comp)right = _merge_sort(items[mid:], comp)return merge(left, right, comp)
  def seq_search(items, key):"""顺序查找"""for index, item in enumerate(items):if item == key:return indexreturn -1
  def bin_search(items, key):"""折半查找"""start, end = 0, len(items) - 1while start <= end:mid = (start + end) // 2if key > items[mid]:start = mid + 1elif key < items[mid]:end = mid - 1else:return midreturn -1
  • 常用算法:

    • 穷举法 - 又称为暴力破解法,对所有的可能性进行验证,直到找到正确答案。
    • 贪婪法 - 在对问题求解时,总是做出在当前看来
    • 最好的选择,不追求最优解,快速找到满意解。
    • 分治法 - 把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题,直到可以直接求解的程度,最后将子问题的解进行合并得到原问题的解。
    • 回溯法 - 回溯法又称为试探法,按选优条件向前搜索,当搜索到某一步发现原先选择并不优或达不到目标时,就退回一步重新选择。
    • 动态规划 - 基本思想也是将待求解问题分解成若干个子问题,先求解并保存这些子问题的解,避免产生大量的重复运算。

    穷举法例子:百钱百鸡和五人分鱼。

  # 公鸡5元一只 母鸡3元一只 小鸡1元三只# 用100元买100只鸡 问公鸡/母鸡/小鸡各多少只for x in range(20):for y in range(33):z = 100 - x - yif 5 * x + 3 * y + z // 3 == 100 and z % 3 == 0:print(x, y, z)# A、B、C、D、E五人在某天夜里合伙捕鱼 最后疲惫不堪各自睡觉# 第二天A第一个醒来 他将鱼分为5份 扔掉多余的1条 拿走自己的一份# B第二个醒来 也将鱼分为5份 扔掉多余的1条 拿走自己的一份# 然后C、D、E依次醒来也按同样的方式分鱼 问他们至少捕了多少条鱼fish = 6while True:total = fishenough = Truefor _ in range(5):if (total - 1) % 5 == 0:total = (total - 1) // 5 * 4else:enough = Falsebreakif enough:print(fish)breakfish += 5

贪婪法例子:假设小偷有一个背包,最多能装20公斤赃物,他闯入一户人家,发现如下表所示的物品。很显然,他不能把所有物品都装进背包,所以必须确定拿走哪些物品,留下哪些物品。

名称价格(美元)重量(kg)
电脑20020
收音机204
17510
花瓶502
101
油画909
  """贪婪法:在对问题求解时,总是做出在当前看来是最好的选择,不追求最优解,快速找到满意解。输入:20 6电脑 200 20收音机 20 4钟 175 10花瓶 50 2书 10 1油画 90 9"""class Thing(object):"""物品"""def __init__(self, name, price, weight):self.name = nameself.price = priceself.weight = weight@propertydef value(self):"""价格重量比"""return self.price / self.weightdef input_thing():"""输入物品信息"""name_str, price_str, weight_str = input().split()return name_str, int(price_str), int(weight_str)def main():"""主函数"""max_weight, num_of_things = map(int, input().split())all_things = []for _ in range(num_of_things):all_things.append(Thing(*input_thing()))all_things.sort(key=lambda x: x.value, reverse=True)total_weight = 0total_price = 0for thing in all_things:if total_weight + thing.weight <= max_weight:print(f'小偷拿走了{thing.name}')total_weight += thing.weighttotal_price += thing.priceprint(f'总价值: {total_price}美元')if __name__ == '__main__':main()

分治法例子:[快速排序]

  """快速排序 - 选择枢轴对元素进行划分,左边都比枢轴小右边都比枢轴大"""def quick_sort(items, comp=lambda x, y: x <= y):items = list(items)[:]_quick_sort(items, 0, len(items) - 1, comp)return itemsdef _quick_sort(items, start, end, comp):if start < end:pos = _partition(items, start, end, comp)_quick_sort(items, start, pos - 1, comp)_quick_sort(items, pos + 1, end, comp)def _partition(items, start, end, comp):pivot = items[end]i = start - 1for j in range(start, end):if comp(items[j], pivot):i += 1items[i], items[j] = items[j], items[i]items[i + 1], items[end] = items[end], items[i + 1]return i + 1

回溯法例子:[骑士巡逻]

  """递归回溯法:叫称为试探法,按选优条件向前搜索,当搜索到某一步,发现原先选择并不优或达不到目标时,就退回一步重新选择,比较经典的问题包括骑士巡逻、八皇后和迷宫寻路等。"""import sysimport timeSIZE = 5total = 0def print_board(board):for row in board:for col in row:print(str(col).center(4), end='')print()def patrol(board, row, col, step=1):if row >= 0 and row < SIZE and \col >= 0 and col < SIZE and \board[row][col] == 0:board[row][col] = stepif step == SIZE * SIZE:global totaltotal += 1print(f'第{total}种走法: ')print_board(board)patrol(board, row - 2, col - 1, step + 1)patrol(board, row - 1, col - 2, step + 1)patrol(board, row + 1, col - 2, step + 1)patrol(board, row + 2, col - 1, step + 1)patrol(board, row + 2, col + 1, step + 1)patrol(board, row + 1, col + 2, step + 1)patrol(board, row - 1, col + 2, step + 1)patrol(board, row - 2, col + 1, step + 1)board[row][col] = 0def main():board = [[0] * SIZE for _ in range(SIZE)]patrol(board, SIZE - 1, SIZE - 1)if __name__ == '__main__':main()

动态规划例子:子列表元素之和的最大值。

说明:子列表指的是列表中索引(下标)连续的元素构成的列表;列表中的元素是int类型,可能包含正整数、0、负整数;程序输入列表中的元素,输出子列表元素求和的最大值,例如:

输入:1 -2 3 5 -3 2

输出:8

输入:0 -2 3 5 -1 2

输出:9

输入:-9 -2 -3 -5 -3

输出:-2

  def main():items = list(map(int, input().split()))overall = partial = items[0]for i in range(1, len(items)):partial = max(items[i], partial + items[i])overall = max(partial, overall)print(overall)if __name__ == '__main__':main()

说明:这个题目最容易想到的解法是使用二重循环,但是代码的时间性能将会变得非常的糟糕。使用动态规划的思想,仅仅是多用了两个变量,就将原来 O ( N 2 ) O(N^2) O(N2)复杂度的问题变成了 O ( N ) O(N) O(N)

函数的使用方式

  • 将函数视为“一等公民”

    • 函数可以赋值给变量
    • 函数可以作为函数的参数
    • 函数可以作为函数的返回值
  • 高阶函数的用法(filtermap以及它们的替代品)

  items1 = list(map(lambda x: x ** 2, filter(lambda x: x % 2, range(1, 10))))items2 = [x ** 2 for x in range(1, 10) if x % 2]
  • 位置参数、可变参数、关键字参数、命名关键字参数

  • 参数的元信息(代码可读性问题)

  • 匿名函数和内联函数的用法(lambda函数)

  • 闭包和作用域问题

    • Python搜索变量的LEGB顺序(Local >>> Embedded >>> Global >>> Built-in)

    • globalnonlocal关键字的作用

      global:声明或定义全局变量(要么直接使用现有的全局作用域的变量,要么定义一个变量放到全局作用域)。

      nonlocal:声明使用嵌套作用域的变量(嵌套作用域必须存在该变量,否则报错)。

  • 装饰器函数(使用装饰器和取消装饰器)

    例子:输出函数执行时间的装饰器。

  def record_time(func):"""自定义装饰函数的装饰器"""@wraps(func)def wrapper(*args, **kwargs):start = time()result = func(*args, **kwargs)print(f'{func.__name__}: {time() - start}秒')return resultreturn wrapper

如果装饰器不希望跟print函数耦合,可以编写可以参数化的装饰器。

  from functools import wrapsfrom time import timedef record(output):"""可以参数化的装饰器"""def decorate(func):@wraps(func)def wrapper(*args, **kwargs):start = time()result = func(*args, **kwargs)output(func.__name__, time() - start)return resultreturn wrapperreturn decorate
  from functools import wrapsfrom time import timeclass Record():"""通过定义类的方式定义装饰器"""def __init__(self, output):self.output = outputdef __call__(self, func):@wraps(func)def wrapper(*args, **kwargs):start = time()result = func(*args, **kwargs)self.output(func.__name__, time() - start)return resultreturn wrapper

说明:由于对带装饰功能的函数添加了@wraps装饰器,可以通过func.__wrapped__方式获得被装饰之前的函数或类来取消装饰器的作用。

例子:用装饰器来实现单例模式。

  from functools import wrapsdef singleton(cls):"""装饰类的装饰器"""instances = {}@wraps(cls)def wrapper(*args, **kwargs):if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper@singletonclass President:"""总统(单例类)"""pass

提示:上面的代码中用到了闭包(closure),不知道你是否已经意识到了。还没有一个小问题就是,上面的代码并没有实现线程安全的单例,如果要实现线程安全的单例应该怎么做呢?

线程安全的单例装饰器。

  from functools import wrapsfrom threading import RLockdef singleton(cls):"""线程安全的单例装饰器"""instances = {}locker = RLock()@wraps(cls)def wrapper(*args, **kwargs):if cls not in instances:with locker:if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return wrapper

提示:上面的代码用到了with上下文语法来进行锁操作,因为锁对象本身就是上下文管理器对象(支持__enter____exit__魔术方法)。在wrapper函数中,我们先做了一次不带锁的检查,然后再做带锁的检查,这样做比直接加锁检查性能要更好,如果对象已经创建就没有必须再去加锁而是直接返回该对象就可以了。

重要知识点

因为五一的原因,无奈托更了几天,还请大家谅解,从今天开始仍然会每天为大家分享Python的知识,而且从本片博客开始,也正是进入了Python第二阶段,大家一起加油吧!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/7166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java的java.util.concurrent.ExecutorService简介

在Java并发编程的璀璨星空中&#xff0c;ExecutorService无疑是那颗最耀眼的明星。它不仅是Java并发编程的核心组件之一&#xff0c;更是构建高并发、高性能应用的秘密武器。今天&#xff0c;我们就来一场说走就走的探索之旅&#xff0c;揭开它的神秘面纱&#xff01; &#x1…

深度学习中的不确定性量化:技术、应用和挑战综述(一)

不确定性量化(UQ)在减少优化和决策过程中的不确定性方面起着关键作用&#xff0c;应用于解决各种现实世界的科学和工程应用。贝叶斯近似和集成学习技术是文献中使用最广泛的两种UQ方法。在这方面&#xff0c;研究人员提出了不同的UQ方法&#xff0c;并测试了它们在各种应用中的…

Ansible自动化运维工具单模块介绍

前言 自动化运维是指利用自动化工具和技术来简化、自动化和优化IT基础设施的管理和运维过程&#xff0c;从而提高效率、降低成本&#xff0c;并减少人为错误。在当今复杂的IT环境中&#xff0c;自动化运维已经成为许多组织和企业提高生产力和保证系统稳定性的重要手段。Ansibl…

动态规划算法:路径问题

例题一 解法&#xff08;动态规划&#xff09;&#xff1a; 算法思路&#xff1a; 1. 状态表⽰&#xff1a; 对于这种「路径类」的问题&#xff0c;我们的状态表⽰⼀般有两种形式&#xff1a; i. 从 [i, j] 位置出发&#xff0c;巴拉巴拉&#xff1b; ii. 从起始位置出…

使用Simcenter全面评估SiC 器件的特性

内容摘要 传统的硅金属-氧化物-半导体场效应晶体管 (MOSFET) 具有成熟的技术和低廉的成本&#xff0c;在中压和绝缘栅双极晶体管 (IGBT) 高压功率电子器件中占主导地位。使用碳化硅等具有高电离能的新型宽带隙材料&#xff0c;可以制造出具有快速开关时间和超过1,000伏击穿电压…

博客网站SpringBoot+Vue项目练习

博客网站SpringBootVue简单案例 前言 学了vue后一直没用找到应用的机会&#xff0c;在Github上找到了一个看起来比较友好的项目&#xff08;其实具体代码我还没看过&#xff09;。而且这个项目作者的readme文档写的也算是比较好的了。 项目链接&#xff1a;https://github.c…

【LeetCode刷题】739. 每日温度(单调栈)

1. 题目链接2. 题目描述3. 解题方法4. 代码 1. 题目链接 739. 每日温度 2. 题目描述 3. 解题方法 用一个栈st保存每个数的下标&#xff0c;同时创建一个数组res保存结果&#xff0c;初始值都为0。循环遍历题目中的数组temperature。如果temperature[i] > st.top()&#x…

Linux--IIC驱动编程实验

对于 I2C 主机驱动&#xff0c;一旦编写完成就不需要再做修改&#xff0c;其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想&#xff0c;因此 Linux内核也将 I2C 驱动分为两部分&#xff1a; ①、 I2C 总…

虚拟化之---virtio通信

一、理解virtio的背景 我们知道虚拟化hypervisor大的类型分为两种&#xff0c;全虚拟化和半虚拟化。 在全虚拟化的解决方案中&#xff0c;guest VM 要使用底层 host 资源&#xff0c;需要 Hypervisor 来截获所有的请求指令&#xff0c;然后模拟出这些指令的行为&#xff0c;这样…

Java毕设之学院党员管理系统的设计与实现

运行环境 环境说明: 开发语言:java 框架:springboot&#xff0c;vue JDK版本:JDK1.8 数据库:mysql5.7(推荐5.7&#xff0c;8.0也可以) 数据库工具:Navicat11 开发软件:idea/eclipse(推荐idea) Maven包:Maven3.3.9 系统实现 管理员功能实现 党员管理 管理员进入指定功能操作…

算法学习:二分查找

&#x1f525; 引言 在现代计算机科学与软件工程的实践中&#xff0c;高效数据检索是众多应用程序的核心需求之一。二分查找算法&#xff0c;作为解决有序序列查询问题的高效策略&#xff0c;凭借其对数时间复杂度的优越性能&#xff0c;占据着算法领域里举足轻重的地位。本篇内…

如何使用resource-counter统计跨Amazon区域的不同类型资源数量

关于resource-counter resource-counter是一款功能强大的命令行工具&#xff0c;该工具基于纯Python 3开发&#xff0c;可以帮助广大研究人员跨Amazon区域统计不同类型资源的数量。 该工具在统计完不同区域的各类资源数量后&#xff0c;可以在命令行中输出并显示统计结果。res…

【driver5】调用堆栈函数,printk,动态打印,ftrace,proc,sysfs

文章目录 1.内核函数调用堆栈&#xff1a;4个函数2.printk&#xff1a;cat /proc/cmdline查看consolettyS03.动态打印&#xff1a;printk是全局的且只能设打印等级&#xff0c;动态打印可控制选择模块的打印&#xff0c;在内核配置打开CONFIG_DYNAMIC_DEBUG4.ftrace&#xff1a…

贪吃蛇项目(小白保姆级教程)

游戏介绍 游戏背景&#xff1a; 贪吃蛇游戏是经典的游戏项目之一&#xff0c;也是很简单的小游戏 实现背景&#xff1a; 这里我们是基于32位的Win32_API进行实现的 需要的知识点&#xff1a; C语言函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32_API等 适合人群&a…

分布式光伏管理系统和一般的光伏管理系统相比有什么区别?

随着全球对可再生能源的关注度日益提高&#xff0c;光伏技术作为其中的佼佼者&#xff0c;已经得到了广泛的应用。在光伏技术中&#xff0c;管理系统扮演着至关重要的角色&#xff0c;它关乎着光伏电站的运行效率、能源产出以及运维成本等多个方面。其中&#xff0c;分布式光伏…

搜索算法系列之四(斐波那契)

以下算法被验证过&#xff0c;如有什么问题或有补充的欢迎留言。 前言 斐波那契数列&#xff0c;又称黄金分割数列&#xff0c;是由意大利数学家&#xff08;Leonardo Fibonacci&#xff09;在1202年提出的。这个数列的递推关系是F(0)1&#xff0c;F(1)1&#xff0c;F(n)F(n-…

【数据库】docker搭建mysql8一主两从节点,配置proxysql读写分离

docker搭建mysql8一主两从节点&#xff0c;配置proxysql读写分离 一、docker 搭建 mysql8 一主两从节点1.1 相关配置文件与docker启动1.2 半同步复制1.3 主从同步异常处理 二、mysql 中间件 ProxySql 配置读写分离2.1 在mysql服务里创建给proxySQL访问的用户2.2 安装ProxySql及…

测试用例执行的结果pass_fail_block_skip

pass fail block skip 测试用例的执行结果通常包括以下几个方面&#xff1a; 1. **测试结果状态**&#xff1a;通常分为“通过”、“失败”、“阻塞”和“跳过”等状态。 - **通过**&#xff1a;测试用例执行完毕&#xff0c;预期结果与实际结果一致。 - **失败**&am…

【MySQL】——用户和权限管理(二)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

大模型争霸的下一站:不仅是超越GPT-4,更是寻求模型之间的平衡应用

文 | 智能相对论 作者 | 沈浪 知名科学杂志《Nature》发表了一篇关于大模型规模参数大小争议的文章《In Al, is bigger always better?》——AI大模型&#xff0c;越大越好吗&#xff1f;随着大模型应用走向实践&#xff0c;这一问题不可避免地成为了当前AI行业发展的焦点与…