Python基础(一)

部署运行你感兴趣的模型镜像

目录

脑图一:

python语言特点

基本语法

标识符

保留字

运算符

1、算数运算符

2、比较运算符

3、赋值运算符

4、位运算符

5、逻辑运算符

6、成员运算符、身份运算符

控制语句

条件语句

循环、控制语句

数据类型

概述

变量赋值

变量的作用域

进制转换

字符串(str)

字符串内置函数

字符串格式化:

列表(list)

列表操作

列表合并

元组

字典

集合set

各结构内置方法 

类型转换

函数

函数定义

函数参数

参数类型

匿名函数

函数举例

1、打乱列表元素

2、回文判断

3、检索质数

高阶函数

内置高阶函数map、filter、reduce

高级特性

切片

迭代、迭代器

生成器、生成式

装饰器

装饰器优势

举例分析流程

闭包

偏函数

内置函数 

模块-包

__init__.py 的作用


脑图一:

python语言特点

解释型语言解释器将代码转换为机器语言,并立即执行;
错误处理解释型语言在运行时发现错误,编译型语言在编译时发现不部分错误
执行速度编译型语言比解释型语言执行更快,因为其代码是直接的机器码
平台依赖编译语言生成平台特定可执行文件,解释型语言则更为跨平台,因为只需要对应平台的解释器

支持面向对象、过程化编程和函数式编程,应用广泛,通过模块和包机制高度复用和模块化设计;

web:Django,Flask等框架                数据分析:Pandas、NumPy等           网络爬虫: Scrapy

人工智能:TensorFlow、Keras      自动化测试:Selenium自动化测试     游戏开发:Pygame库2D

科学计算:Scipy                             区块链: Hyperledger、Ethereum      嵌入式: MicroPython

语言特点:python 最具特色的就是用缩进来写模块。缩进可使用tab或空格,所有代码块语句必须包含相同的缩进空白数量,python支持交互式和脚本式编程

注释:#单行  '''多行注释'''

基本语法

知识点分类具体内容说明与示例
变量与数据类型数字(int, float, complex)a = 10(int),b = 3.14(float),c = 1+2j(complex)
字符串(str)"hello", 'world'
布尔值(bool)True, False
None类型表示空值,x = None
运算符算术运算符+, -, *, /, //, %, **
比较运算符==, !=, <, >, <=, >=
逻辑运算符and, or, not
位运算符&, |,~,>>,<<
控制流条件语句(if-elif-else)根据条件执行不同代码块
循环语句(for, while)重复执行代码块
循环控制(break, continue, else)控制循环流程,else在循环正常结束时执行
函数定义与调用位置参数、关键字参数、默认参数def func(a, b=2):
可变参数(*args, **kwargs)*args接收任意位置参数,**kwargs接收任意关键字参数
匿名函数(lambda)lambda x: x * 2
递归函数函数调用自身实现递归
模块与包import语句import mathfrom os import path
from ... import ...从模块中导入指定对象
包的结构与__init__.py包初始化文件,标识目录为包
注释与文档字符串单行注释、块注释、docstring# 注释"""文档字符串"""

标识符

标识符是允许作为变量(函数、类等)名称的有效字符串。不可以是语言本身保留的标识符,这些是不能做它用的标识符的,否则会引起语法错误(SyntaxError 异常);

Python 是动态类型语言,不像C++那种静态型语言定义的时候都要明确类型,python不需要预先声明变量的类型。变量的类型和值在赋值那一刻被初始化,变量赋值通过等号来执行。

Python的有效标识符由大小写字母、下划线和数字组成,数字不能作为开始字符,标识符的长度一般不限,Python标识符是严格大小写敏感的。

保留字

FalseNoneTrueand as assertasync await breakclass
continuedefdelelifelseexceptfinallyfrom global import
for lambda not with pass while nonlocal yieldraise return
if inisor try
number=12
my_var=1
_temp='hell'  #' ' 与"" 定义字符串,使用#单行注释
str_tem="world"
#1wo='sd' #表示符 error SyntaxError: invalid decimal literal
#if=1  SyntaxError: invalid syntax
def my_func():
    '''
    多行注释,注意行缩进规则
    '''
    sum_temp=number+\
    my_var
    day=['m','t',  #换行
         'w']
    print(sum_temp)  #13
    print(day)       #['m', 't', 'w']
my_func()  

运算符

1、算数运算符

a=12 #0b1010
b=10 #0b1100
print(a+b)  #加    22
print(a-b)  #减    12
print(a*b)  #乘    120
print(a/b)  #除    1.2
print(a%b)  #取模   2
print(a**b) #幂运算 10个12相乘
print(a//b) #向下取整 1

2、比较运算符

a=12 #0b1010
b=10 #0b1100
print(a==b)  #等于     False
print(a!=b)  #不等于   True
print(a>b)   #大于     True
print(a<b)   #小于     False
print(a>=b)  #大于等于  True
print(a<=b)  #小于等于  False

3、赋值运算符

a=12 #0b1010
b=10 #0b1100
c=a+b    #简单赋值   22
c+=a     #加法赋值   34 <>c=c+a
c-=a     #减法赋值   22
c*=b     #乘法赋值   220
c/=a     #除法赋值   18.33333..
c%=b     #取模赋值   8.333333..
b**=a    #幂赋值     1000000000000
a//=b    #取整除赋值      0

4、位运算符

a=12 #0b1010
b=10 #0b1100  
print(a|b)  #14  0b1110
print(a^b)  #6   0b110
print(~a)   #-13 -0b1101
print(a<<2) #48  0b110000
print(a>>1) #6   0b110

5、逻辑运算符

a=12 #0b1010
b=10 #0b1100  
c=0
d=False
#python不像c++, python的逻辑运算不单单返回布尔值
print(a and b)  # 10 a非false,返回b的计算值
print(a and c)  # 0  a非false,返回c的计算值
print(a and d)  # False a非false 返回d的计算值
print(c and a)  # 0 c是false   不计算a
print(d and a)  # False a是false
print(a or b)   # 12  前一个非0,返回前一个
print(b or a)   # 10
print(c or a)   # 12  前一个是0,返回后一个
print(not a)    # Fasle
print(not c)    # True
print(not d)    # True

6、成员运算符、身份运算符

lista=[1,2,3]
a=10
b=a
c=10
listb=[1,2,3]
#涉及到可变量和不可变量,还涉及到缓存问题
#而对于小整数(通常在 -5 到 256 之间),Python会缓存这些对象
#在交互式环境(如Python REPL)中,每行代码是独立执行的,因此
# a = 257 和 b = 257 会创建两个不同的对象。
#但在脚本中运行(如VSCode),Python可能会对代码进行优化,导致 a 和 b 引用同一个对象。
print(1 in lista)      # True 
print(4 in lista)      # False
print(1 not in lista)  # False 
print(4 not in lista)  #True
print(a is c)            #True
print(a == c)            #True
print(a is b)            #True
print(a == b)            #True
print(lista is listb)    #False
print(lista == listb)    #True

控制语句

条件语句

if 语句、if else 语句和 if elif else 语句

#条件控制语句
#1 if else
a=10
if a>=1:
    print("大于1")
else:
    print("小于1")
# if elif else
if 0<=a<=2:
   print("A") 
elif 0<=a<=3:
   print("A-") 
elif 4<=a<=6:
   print("B") 
else:
   print("c") 
#瑞年判断
year = 2024
if (year % 4 == 0 and year % 100 != 0)\
      or year % 400 == 0:
    print(f"{year} 是闰年")
else:
    print(f"{year} 不是闰年")

循环、控制语句

for 循环和 while 循环,亦可嵌套; break、continue、pass

#while循环 contine、break控制
i=1
while i<20:  #判定条件
    i+=1      #执行语句以及下面语句块
    if i%2>0:
        continue   #跳过本次循环
    if i>10:
        break      #退出循环
    print(i,end=" ") #2 4 6 8 10
flag = 1
while (flag>1): print('1!') #组合语句
else:     #while里的else
    print("完成!")
#for循环 contine、break控制
for le in 'abc':
    if le=='b':
        continue
    print(le)  #a c
for i in range(1,10):
    if i==2:
        pass     #pass块
        print('什么也不做')
    if i>5:
        break
    print(i) #1 2 3 4 5

数据类型

概述

变量存储在内存中的值,在创建变量时会在内存中开辟一个空间。基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中,可以执行什么样的操作。python基本数据类型一般分为:数值(Numbers)、字符串(String)、列表(List)、元组(Tuple)、字典(Dictionary)、集合(Set)

1、数值类型:int无限精度只受内存限制,double双精度64位浮点,因计算机的存储表示存在计算精度问题,complex 实部和虚部都是浮点数,(Python3的int是任意精度整数。底层用数组存储多个“数字块”(digit),每个数字块存储固定长度的二进制位。通过多个数字块组合表示大整数,动态扩展内存。运算通过多精度算法逐位计算。因此,int大小只受内存限制。

2、序列类型:str不可变unicode字符集,内存优化字符串缓存, list有序可存储异构数据、tuple有序不可更改

3、映射类型:dict 键值对,键必须是可哈希的不可变类型

4、集合类型:set:可变无序不重复的,frozenset 不可变版本

5、子类化自int: issubclass(bool, int) 返回True仅有两个实例:True(1) 和 False(0)

6、特殊类型:nonetype 唯一值:None表示空值或缺失值二进制类型 bytes:不可变字节序列 b'data' bytearray可变字节序列

数值型int、float、complex版本变化

版本主要变化和特性
Python 2.xintlong分开,long支持任意大整数。
Python 3.0统一intlongint支持任意大整数。
Python 3.1+浮点数性能和精度优化。
Python 3.6+引入math.isclose()等数值辅助函数。
Python 3.8+引入math.prod()等数学函数。

变量赋值

Python 中的变量赋值不需要类型声明,等号 = 用来给变量赋值,变量赋值以后该变量才会被创建,每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。

num = -100 # 赋值有符号整型变量
type(num)  #int
weight = 100.0 # 浮点型
type(weight) #float
name = "hello" # 字符串 or name1='hell' or name2='''hell'''
tye(name) #str
c = 2 + 3j
print(type(c), c)  # <class 'complex'> (2+3j)

# 复数的实部和虚部
print(c.real)  # 2.0
print(c.imag)  # 3.0
bool_value = True # 布尔值
list_val = [1, 2, 3, 4, 5] # 列表
tuple_val = (1, 2, 3, 4, 5) # 元组
dict_val = {'name': 'AC', 'age': 25} # 字典
set_val = {1, 2, 3, 4, 5} # 集合
#创建一个整型对象,值为1,三个变量被分配到相同的内存空间上
a = b = c = 1 #多变量赋值
#两个整形对象和一个字符串对象
a1,b1,c1=1,2,'wold' 

变量的命名规则即标识符的规则,python严格区分大小写,python没有真正的常量机制通常用全大写变量名表示常量约定不修改,可以用del删除变量引用; 变量的内置方法type():查看变量类型isinstance():判断变量是否是某类型;id():查看变量引用的内存地址;vars():返回对象的属性字典(常用于类实例)

不可变类型intfloatstrtuplefrozenset等,变量修改会创建新对象。

可变类型listdictset等,变量修改会改变原对象。

变量的作用域

作用域就是一个 Python 程序可以直接访问命名空间的区域,在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

搜索规则顺序: L –> E –> G –> B在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal

global关键字用于在函数内部声明变量为全局变量。当需要在一个函数内修改全局作用域中的变量时,就需要使用global关键字。

nonlocal关键字用来在函数或其他作用域中使用外层(非全局)变量。它主要用在嵌套函数中,当需要修改嵌套作用域内的变量时使用nonlocal。

z=30
def out_fun():
    y=20
    global z #表明全局变量被修改
    z=39
    print("global z: ",z) #39 if no global 39
    print(len("sf"))  #2 内建函数
    def func():
        x=10 #局部嵌套变量
        nonlocal y #内存修改了外层变量
        y=24
        print("local x: ",x)  #10
        print("Local y: ",y)  #24 if no nonlocal 24
        print("global z: ",z) #39 if no global 39
    func()
    #print(x) #外部不可以调用
    print("out local y: ",y) #24 if no nonlocal 20
out_fun()
print("global z: ",z) #39 if no global 30

进制转换

# 十进制数
decimal_number = 42
# 十进制转其他进制
binary_number = bin(decimal_number)
octal_number = oct(decimal_number)
hexadecimal_number = hex(decimal_number)

print(f"十进制 {decimal_number} 转换为二进制: {binary_number}")  # 输出: 0b101010
print(f"十进制 {decimal_number} 转换为八进制: {octal_number}")  # 输出: 0o52
print(f"十进制 {decimal_number} 转换为十六进制: {hexadecimal_number}")  # 输出: 0x2a

# 其他进制转十进制
binary_string = '101010'
octal_string = '52'
hexadecimal_string = '2a'

decimal_from_binary = int(binary_string, 2)
decimal_from_octal = int(octal_string, 8)
decimal_from_hexadecimal = int(hexadecimal_string, 16)

print(f"二进制 {binary_string} 转换为十进制: {decimal_from_binary}")  # 输出: 42
print(f"八进制 {octal_string} 转换为十进制: {decimal_from_octal}")  # 输出: 42
print(f"十六进制 {hexadecimal_string} 转换为十进制: {decimal_from_hexadecimal}")  # 输出: 42

字符串(str)

str字符串:Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用,支持切片操作

#str基本操作
str_test='Hello'  #创建
str_test[0]     #H []下标取元素
str_test[0:]    #Hello 从0到结尾
str_test[1:4]   #ell  index从1到4,不含4
str_test[8:42]  #''空
#str_test[8]     #IndexError: 越界
str_test[::-1]  #反向遍历(末尾下标-1),反转()
str_test1="World"
str_test+str_test #HelloWorld 拼接
str_test*2      # 'HelloHello' 重复
's' in str_test
print(r'hell\nls') #r/R 原始字符串不转义
#格式化
print("try %s %d"%('hell',20)) #格式化
"{}{}".format('hell','world')  #hellworld
"{1}{0}".format('hell','world')#worldhell
"{1}{0}{1}".format('a','b')    #bab
"{name}, 年龄{age}".format(name="A", age=2)
name = "Alice"
age = 30
# f-string(Python 3.6+)
print(f"My name is {name}, I am {age} years old.")
# format方法
print("My name is {}, I am {} years old.".format(name, age))
# 百分号格式化
print("My name is %s, I am %d years old." % (name, age))

字符串内置函数

s="hello wo"
s.encode(encoding='utf#8', errors='sict') # 返回字符串的编码版本,默认使用 UTF#8 编码
s.endswith('wo') #True 检查字符串是否以指定的后缀结尾,可以指定搜索的范围
s.expandtabs(tabsize=8) # 替换字符串中的 tab 符号(\t),默认一个 tab 替换为 8 个空格
s.find('wo') #6  找到子串 sub 第一次出现的位置,可以指定搜索的范围(start,end)
s.index('ll') #2 和 s.find 类似,但如果子串不存在会抛出异常
s.isalnum() #False 检查字符串是否只包含字母和数字
s.isalpha() #False 检查字符串是否只包含字母
s.isdecimal() #False 检查字符串是否只包含十进制数字
s.isdigit() #False 检查字符串是否只包含数字
s.islower() #True 检查字符串中所有的字母是否都是小写
s.isnumeric() #False 检查字符串中所有的字符是否都是数字
s.isspace() #False 检查字符串是否只包含空格
s.istitle() #False 检查字符串中的单词是否都是首字母大写
s.isidentifier() # 是否是有效的标识符
s.isprintable() #True 检查字符串中的字符是否都是可打印的
s.join('abc') #ahello wobhello woc 将可迭代对象中的元素连接起来,元素必须都是字符串
s.ljust(6) # 返回一个指定宽度 width 左对齐的字符串,默认使用空格填充
s.lower() # 将字符串中的所有大写字母转换为小写
s.lstrip() # 去除字符串左侧的空白或指定字符lsip([chars])
s.rstrip() # 去除字符串右侧的空白或指定字符lsip([chars])
s.strip() #首尾空格
s.replace('wo', 'world') # 返回字符串中 old 被替换为 new 的新字符串,可以指定最大替换次数
s.rfind('l') #3 和 s.find 类似,但从右边开始搜索
s.rindex('l') #3 和 s.index 类似,但从右边开始搜索
s.rjust(7) # 返回一个指定宽度 width 右对齐的字符串,默认使用空格填充
s.rpartition(' ') # 类似 s.partition,但是从右边开始搜索分隔符
s.upper() #'HELLO WO' 转大写
s.lower() #转小写
s.capitalize() #'Hello wo' 首字母大写
s.title()      #'Hello Wo' 标题化 每个单词大写
s.casefold() # hello wo 返回一不区分大小写字符串
s.center(10,*) # *hello wo* 返回指定宽度字符串,默认填充空,你可以指定
s.count('h') #count(substring, start=0, end=len(string)) 统计
s.format("word") #s="hello,{}"  输出hello,word 
s.format_map({'name':'world'}) #s='hello,{name}'  输出hell,world
s.s.partition(" ") #('Hello',' ','wo')

常用

s = "  hello world, hello Python  "

print(s.split())  # ['hello', 'world,', 'hello', 'Python']
print(s.split(','))  # ['  hello world', ' hello Python  ']
print(",".join(['apple', 'banana', 'cherry']))  # apple,banana,cherry
print(s.strip())  # 去除首尾空白 'hello world, hello Python'
print(s.replace("hello", "hi"))  # '  hi world, hi Python  '
print(s.find("world"))  # 9,找到第一个匹配的索引
print(s.count("hello"))  # 2,出现次数

字符串格式化:

百分号(%)格式化str.format()方法 Python 2.7

%s:字符串

{}:占位符,用于插入变量或值

{:d}:整数    {:f}:浮点数    {:s}:字符串   

%d:十进制整数

{:x}:十六进制整数(小写){:X}:十六进制整数(大写)  

%f:浮点数

{:e}:科学计数法

%x:十六进制整数(小写)

{:g}:自动选择浮点形式或科学计数法 

%X:十六进制整数(大写)

{:o}:八进制数 

%e:科学计数法表示的浮点数

{:.n}:指定小数点后的位数(n为数字)

%g:根据数值的大小,自动选择使用浮点形式或科学计数法表示

 {:>m}:右对齐,m为宽度 

%o:八进制数

{:<m}:左对齐,m为宽度

%%:字面上的百分号{:^m}:居中对齐,m为宽度

name = "Alice"

age = 30

print("Hello, %s. You are %d years old." % (name, age))

print("Hello, {}. You are {} years old.".format(name, age))

print("Pi is approximately {:.2f}.".format(3.1415926))

格式化字符串字面量(f-strings)这是Python 3.6

{变量名}:直接插入变量{变量名:d}:整数              {变量名:s}:字符串   

{变量名:f}:浮点数   

{变量名:o}:八进制数 

{变量名:x}:十六进制整数(小写)   

{变量名:X}:十六进制整数(大写)   

{变量名:e}:科学计数法   

{变量名:g}:自动选择浮点形式或科学计数法   

{变量名:^m}:居中对齐,m为宽度

{变量名:.n}:指定小数点后的位数(n为数字)   

{变量名:>m}:右对齐,m为宽度   

{变量名:<m}:左对齐,m为宽度

name = "Alice"
age = 30
print(f"Hello, {name}. You are {age} years old.")
pi = 3.1415926
print(f"Pi is approximately {pi:.2f}.")
版本主要变化和特性
Python 2.x区分str(字节串)和unicode,编码处理复杂。
Python 3.0彻底统一为Unicode字符串,str即Unicode,bytes为字节串。
Python 3.3引入灵活的字符串内部表示(PEP 393),根据内容自动选择存储编码,节省内存。
Python 3.6+字符串格式化增强,支持f-string(格式化字符串字面量)。
Python 3.7+字符串性能和内存优化持续进行。

列表(list)

list序列可以进行的操作包括索引,切片,加,乘,检查成员。元素可以是list,列表的数据项不需要具有相同的类型。

#创建list
list1 = ['python', 'hell', 2024]
list2 = []    #空列表
list3 = ["a", "b", "c", "d"]
list1[0]       #索引取值
list1[-1]      #2024
list1[:]       #切片遍历所有
list1[1:2]     #hell 左闭右开
list1[::-1]    #反向遍历
list2.append('baidu') #添加元素
del list1[0]   #['hell0', 2024]
len(list1)     #2 长度
max(list3)     #最大元素,元素类型需要一致
min(list3)
[1,2]+[2,3]    #组合
['h']*3        #['h','h','h] 重复
3 in [1,3]     # True 
for i in [1,2,3]: print(i)
print(list((1,2))) #元组转列表

列表操作

#list列表操作
la = ['a', 'b', 'a', 'c']
la1=['k','p']
#list.append(obj) 	在列表末尾添加新的对象
la.append('g') #['a', 'b', 'a', 'c', 'g']
#在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
la.extend(la1)  #['a', 'b', 'a', 'c', 'g', 'k', 'p']
la.count('a') #2  list.count(obj) 统计某个元素在列表中出现的次数
la.index('b')  #1  list.index(obj) 从列表中找出某个值第一个匹配项的索引位置
la.insert(0,'x') # list.insert(index, obj) 	将对象插入列表
#ist.pop([index=-1]) 	移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
la.pop()  #['x', 'a', 'b', 'a', 'c', 'g', 'k']
la.pop(0)  #['a', 'b', 'a', 'c', 'g', 'k']
#list.remove(obj) 	移除列表中某个值的第一个匹配项
la.remove('a')  #['b', 'a', 'c', 'g', 'k']
la.reverse() #['k', 'g', 'c', 'a', 'b'] 反向列表中元素
#list.sort(cmp=None, key=None, reverse=False) 	对原列表进行排序
la.sort()#['a', 'b', 'c', 'g', 'k']

列表合并

1、直接使用+, 这样会创建新类表不适合较大列表,

2、list.extend(lis) 直接修改源列表不创建新的内存高效

3、切片list[len(lis):]=lis等同于list

4、解包操作merged = [*list1, *list2] 可同时合并多个列表不会修改原列表

5、itertools.chain()(高效迭代器)merged = list(chain(list1, list2))延迟计算,内存效率最高,缺点:需要额外转换为列表

去重合并 merged = list(set(list1 + list2));

交替合并 from itertools import zip_longest

merged = [x for pair in zip_longest(list1, list2) for x in pair if x is not None]

按条件合并:merged = [x for x in list1 if x > 2] + [x for x in list2 if x != 'b']

版本主要变化和特性
Python 2.x列表是动态数组,支持常用操作,性能逐步优化。
Python 3.0移除listsort()返回值(改为就地排序,返回None),统一字符串编码。
Python 3.3+引入list.copy()方法,方便复制列表。
Python 3.4+list__reversed__()方法性能优化。
Python 3.7+列表内部实现细节优化,性能提升,但接口无大改动。

元组

元组的元素不能修改,创建空元组tp=(), 只有一个元素tp=(1,); 元组与字符串类似,下标索引从0开始,可以进行截取,组合等。

#tuple元组操作
tup=(1,2,3)       #创建
tup[0]            #1  下标获取
tup[:]     #(1,2,3)
tup[1:2]   #(2,) 
tup[::-1]  #(3,2,1)
#tup[0]=10  #TypeError不支持修改
del tup  #元素不可删除,可删除整个元组
len((1,2,3)) #3 计算元素个数
(1,2)+(2,) #(1, 2, 2) 连接
(1,)*3     #(1,1,1) 复制
3 in (1,2,3)  #True 元素存在否
for i in (1,2,3): print(1)
max((1,2,3)) #3 求最大最小数据类型要一致
#min(('1',2,3)) #TypeError
#内置方法'count', 'index' tup.index(1) tup.count(1) 
版本主要变化和特性
Python 2.x元组是不可变序列,支持拆包、比较等。
Python 3.0语法和行为基本保持一致,增强了类型注解支持。
Python 3.6+引入了typing.NamedTuple,支持更丰富的类型定义。
Python 3.7+引入dataclasses,提供类似元组的轻量数据结构。

字典

可变容器且可存储任意类型对象,字典的每个键值 key=>value  : 分割,每个键值对之间用逗号 , 分割,整个字典在 {} 中 ,eg: d = {key1 : v1, key2 : v2 }键一般是唯一的,如果重复最后的一个键值对会替换前面的,值不需要唯一

#dict操作
dict = {'a': 1, 'b': 2}  #创建
dict['a']           #key获取val
#dict['0']           #KeyError
dict['a']=0   #{'a': 0, 'b': '3'} 更新
dict['c']=3   #{'a': 0, 'b': '3', 'c': 0}
del dict['c'] #{'a': 0, 'b': '3'}
dict.clear()  #{} 清空
del dict      #删除字典
d1={'a':1,'b':2}
#dict1={[1,2]:1} #key是不可变
d1.keys()   #dict_keys(['a', 'b'])
d1.values() #dict_values([1, 2])
d1.items()  #dict_items([('a', 1), ('b', 2)])
# 创建一个字典
my_dict = {
    'name': 'Alice',
    'age': 30,
    'city': 'New York'
}

# 1. clear() - 清空字典
my_dict.clear()
print("After clear():", my_dict)  # 输出: {}

# 2. copy() - 复制字典
my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}  # 重新创建字典
copied_dict = my_dict.copy()
print("Copied dictionary:", copied_dict)  # 输出: {'name': 'Alice', 'age': 30, 'city': 'New York'}

# 3. fromkeys() - 创建一个新字典,使用指定的键和默认值
keys = ['name', 'age', 'city']
new_dict = dict.fromkeys(keys, 'unknown')
print("New dictionary from keys:", new_dict)  # 输出: {'name': 'unknown', 'age': 'unknown', 'city': 'unknown'}

# 4. get(key, default=None) - 获取指定键的值,如果键不存在则返回默认值
name = my_dict.get('name', 'Not Found')
print("Get name:", name)  # 输出: Alice

# 5. items() - 返回字典的 (键, 值) 对的视图
items = my_dict.items()
print("Items in dictionary:", list(items))  # 输出: [('name', 'Alice'), ('age', 30), ('city', 'New York')]

# 6. keys() - 返回字典的键的视图
keys = my_dict.keys()
print("Keys in dictionary:", list(keys))  # 输出: ['name', 'age', 'city']

# 7. pop(key, default=None) - 移除指定键并返回其值,如果键不存在则返回默认值
age = my_dict.pop('age', 'Not Found')
print("Popped age:", age)  # 输出: 30
print("After pop('age'):", my_dict)  # 输出: {'name': 'Alice', 'city': 'New York'}

# 8. popitem() - 移除并返回字典中的最后一对 (键, 值)
last_item = my_dict.popitem()
print("Popped item:", last_item)  # 输出: ('city', 'New York')
print("After popitem():", my_dict)  # 输出: {'name': 'Alice'}

# 9. setdefault(key, default=None) - 如果键不存在,则插入键并设置默认值
my_dict.setdefault('age', 30)
print("After setdefault('age', 30):", my_dict)  # 输出: {'name': 'Alice', 'age': 30}

# 10. update(other) - 用其他字典的键值对更新字典
my_dict.update({'city': 'Los Angeles', 'country': 'USA'})
print("After update():", my_dict)  # 输出: {'name': 'Alice', 'age': 30, 'city': 'Los Angeles', 'country': 'USA'}

# 11. values() - 返回字典的值的视图
values = my_dict.values()
print("Values in dictionary:", list(values))  # 输出: ['Alice', 30, 'Los Angeles', 'USA']

字典是无序的,从3.7+开始字典保持插入顺序,遍历字典时和插入顺序一致,你想依赖于顺序做业务你可以优先使用collections.OrderedDict

版本主要变化和特性
Python 2.x字典无序,基于哈希表实现,性能逐步优化。
Python 3.3引入dictview对象(如dict.keys()返回视图),更高效。
Python 3.6CPython实现中开始保持插入顺序(实现细节,非语言规范)。
Python 3.7+官方语言规范保证字典保持插入顺序,遍历顺序与插入顺序一致。
Python 3.8+引入dict合并和更新运算符:`d1 

d1 | d2:返回一个新的字典,是将d1d2合并后的结果,d2中的键会覆盖d1中相同的键。

d1 |= d2:就地更新d1,相当于d1.update(d2)

集合set

集合(Set)是一个无序的不重复元素序列,可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。

元素无序、元素不可更改、元素类型可以是各种类型、集合不允许有重复元素

#集合set
sp={1,2,3,1}    #{1, 2, 3} 去重
a=set('abcaf') #{'c', 'b', 'a','f'}
b=set('abcde') 
a-b        #{'f'} 集合a中包含而集合b中不包含的元素
a|b        #{'b', 'f', 'c', 'e', 'a', 'd'} 集合a或b中包含的所有元素
a&b        #{'a', 'c', 'b'} 集合a和b中都包含了的元素
a^b        #{'d', 'f', 'e'} 不同时包含于a和b的元素
#添加元素
#s.add(x) 将元素 x 添加到集合 s 中,如果元素已存在,则不进行任何操作
a.add('r') #{'r', 'b', 'a', 'f', 'c'} 元素顺序每一次输出不一定一致
#s.update(x) 且参数可以是列表,元组,字典等
a.update('x') #{'x', 'f', 'a', 'b', 'r', 'c'}
a.update(['y','z']) #{'y', 'a', 'f', 'c', 'x', 'z', 'r', 'b'}
#移除元素
a.remove('x') #{'c', 'y', 'z', 'b', 'a', 'f', 'r'}
#a.remove('x') #KeyError: 'x'
a.discard('y') #{'z', 'r', 'a', 'b', 'f', 'c'}
a.discard('y') #不存在也不会报错
len(a) #6
'x' in a  #判断元素是否在集合中存在
print(a.difference(b)) #{'f', 'r', 'z'} 返回多个集合的差集
print(a.intersection(b)) #{'c', 'a', 'b'} 返回集合的交集
print(a.isdisjoint(b))  #False 判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
print(a.issubset(b))    #False 判断指定集合是否为该方法参数集合的子集。
数据类型重要版本关键变化或特性
列表3.3新增list.copy()
3.7+性能优化,接口稳定
元组3.6+typing.NamedTuple支持
3.7+dataclasses引入,类似元组的轻量数据结构
字典3.3引入视图对象
3.6CPython实现保持插入顺序(实现细节)
3.7+官方保证插入顺序
3.8+新增合并和更新运算符
字符串3.0统一Unicode字符串
3.3灵活字符串内部表示(PEP 393)
3.6+f-string支持
数值型3.0统一intlong
3.6+新增数值辅助函数
3.8+新增数学函数

各结构内置方法 

数据结构方法名描述示例代码
listappend(x)在列表末尾添加元素 xmy_list.append(4) #  [1, 2, 3, 4]
extend(iterable)在列表末尾添加多个元素my_list.extend([5, 6]) #  [1, 2, 3, 4, 5, 6]
insert(i, x)在指定位置 i 插入元素 xmy_list.insert(1, 10) #  [1, 10, 2, 3, 4, 5, 6]
pop([i])移除并返回指定位置的元素(默认最后一个元素)last_element = my_list.pop() # last_element 为 6
remove(x)移除列表中第一个匹配的元素 xmy_list.remove(10) #  [1, 2, 3, 4, 5]
reverse()反转列表中的元素my_list.reverse() #  [5, 4, 3, 2, 1]
sort(key=None, reverse=False)对列表进行排序my_list.sort() #  [1, 2, 3, 4, 5]
clear()清空列表my_list.clear() #[]
count()统计元素个数my_list.count(1)  #1
index()查看元素位置my_list.index(1) #0 
my_list.index(11)#11 not in list 
copy()列表拷贝l1=my_list.copy()
tuplecount(x)返回元素 x 在元组中出现的次数my_tuple.count(2)
index(x)返回元素 x 在元组中第一次出现的索引my_tuple.index(2)
dictclear()清空字典中的所有键值对my_dict.clear() # my_dict 变为 {}
copy()返回字典的浅拷贝copied_dict = my_dict.copy() # 复制字典
fromkeys(keys, value=None)创建一个新字典,使用指定的键和默认值new_dict = dict.fromkeys(['a', 'b', 'c'], 0) # new_dict 为 {'a': 0, 'b': 0, 'c': 0}
get(key, default=None)返回指定键的值,如果键不存在则返回默认值value = my_dict.get('a', 'Not Found') # value 为 'Not Found'
items()返回字典的 (键, 值) 对的视图items = my_dict.items() # 返回字典的键值对视图
keys()返回字典的键的视图keys = my_dict.keys() # 返回字典的键视图
pop(key, default=None)移除指定键并返回其值,如果键不存在则返回默认值value = my_dict.pop('a', 'Not Found') # 移除键 'a' 的值
popitem()移除并返回字典中的最后一对 (键, 值)last_item = my_dict.popitem() # 移除并返回最后一对 (键, 值)
setdefault(key, default=None)如果键不存在,则插入键并设置默认值my_dict.setdefault('c', 3) # 如果 'c' 不存在,则设置为 3
update(other)用其他字典的键值对更新字典my_dict.update({'d': 4}) # 更新字典
values()返回字典的值的视图values = my_dict.values() # 返回字典的值视图
seta = {1, 2, 3, 4} b = {3, 4, 5, 6}
add()添加元素a.add(5) # {1, 2, 3, 4, 5}
clear()清空集合c = a.copy() c.clear() # set()
copy()集合的浅拷贝c = a.copy() print(c is a) # False
difference(*others)返回当前集合与其他集合的差集(不修改原集合)diff = a.difference(b) print(diff) # {1, 2, 5},a中有但b中没有的元素
difference_update(*others)原地更新集合,移除与其他集合共有的元素(差集赋值给自己)a.difference_update(b) print(a) # {1, 2, 5}
discard(elem)移除元素elem,如果元素不存在也不会报错

a.discard(5) print(a)  # {1, 2}
a.discard(10)  # 不报错,元素10不存在
print(a)  # {1, 2}

intersection(*others)返回集合的交集(不修改原集合)a = {1, 2, 3, 4} inter = a.intersection(b) print(inter) # {3, 4}
intersection_update(*others)原地更新集合,只保留与其他集合共有的元素(交集赋值给自己)a.intersection_update(b) print(a) # {3, 4}
 
isdisjoint(other)判断两个集合是否没有交集,没有交集返回True,否则Falseissuperset(other)
判断当前集合是否是other集合的超集

issubset(other)
判断当前集合是否是other集合的子集

pop()
随机移除并返回一个元素,集合为空时会报错
symmetric_difference(other)
返回当前集合和other集合的对称差集(不修改原集合)
symmetric_difference_update(other)
原地更新集合,赋值为对称差集
union(*others)
返回当前集合与其他集合的并集(不修改原集合)
update(*others)
原地更新集合,添加其他集合的所有元素(并集赋值给自己)
remove(elem)
移除元素elem,元素不存在时会报错KeyError

 特有方法

方法名类型功能简述
bit_length()int返回整数的二进制表示中有效位数
to_bytes(length, byteorder)int将整数转换为指定长度和字节序的字节序列
from_bytes(bytes, byteorder)int (类方法)从字节序列转换为整数
is_integer()float判断浮点数是否为整数值(小数部分为0)
hex()float返回浮点数的十六进制表示字符串
fromhex() (类方法)float从十六进制字符串转换为浮点数
real (属性)complex返回复数的实部
imag (属性)complex返回复数的虚部
append(x)list在列表末尾添加元素
clear()list/set/dict清空所有元素
copy()list/set/dict返回浅拷贝
extend(iterable)list在列表末尾扩展多个元素
insert(i, x)list在指定位置插入元素
pop([i])list/set移除并返回指定位置元素(set无参数随机移除)
remove(x)list/set移除第一个匹配元素(set中移除指定元素)
reverse()list原地反转列表元素
sort(key=None, reverse=False)list原地排序列表元素
*difference(others)set返回当前集合与其他集合的差集
*difference_update(others)set原地移除当前集合中与其他集合共有的元素
discard(elem)set移除元素,如果元素不存在不会报错
*intersection(others)set返回当前集合与其他集合的交集
*intersection_update(others)set原地保留当前集合与其他集合的交集
isdisjoint(other)set判断两个集合是否没有交集
issubset(other)set判断当前集合是否是另一个集合的子集
issuperset(other)set判断当前集合是否包含另一个集合
symmetric_difference(other)set返回两个集合的对称差集(不在交集中的元素)
symmetric_difference_update(other)set原地更新为对称差集
*union(others)set返回多个集合的并集
*update(others)set/dict原地添加其他集合或字典的元素
fromkeys(iterable, value=None)dict (类方法)创建新字典,键来自可迭代对象,值为指定默认值
get(key, default=None)dict返回指定键的值,键不存在时返回默认值
items()dict返回字典键值对视图
keys()dict返回字典所有键的视图
pop(key, default=...)dict移除指定键并返回对应值,键不存在时返回默认值或报错
popitem()dict随机移除并返回一对键值对
setdefault(key, default=None)dict如果键不存在,插入键并设置默认值,返回对应值
values()dict返回字典所有值的视图

类型转换

int()将一个数或字符串转换成整数num = int("123")  # 把字符串"123"转换成整数123
非数字型转换int("a")  报 ValueError: invalid literal for int() with base 10: 'a'
float()

将一个数或字符串转换成浮点数float('12') #把字符串"12"转换成整数12.0

float('w2') error  ValueError: could not convert string to float: 'w2'

str()

将对象转换成字符串。str_num = str(123)  # 把整数123转换成字符串"123"

bool()

将对象转换成布尔值。flag = bool(1)  # 把整数1转换成布尔值True

list()

将任何可迭代对象(如元组、字符串、集合等)转换成列表。lst = list((1, 2, 3))  # 把元组(1, 2, 3)转换成列表[1, 2, 3]

tuple()

将任何可迭代对象转换成元组。tpl = tuple([1, 2, 3])  # 把列表[1, 2, 3]转换成元组(1, 2, 3)

set()

将任何可迭代对象转换成集合,集合中的元素是唯一的。s = set([1, 2, 2])  # 列表转换成集合{1, 2}

dict()创建一个字典,或者将键值对序列转换成字典。d = dict(a=1, b=2)  # 创建一个字典{'a': 1, 'b': 2}
chr()将一个Unicode编码转换成对应的字符。char = chr(65)  # 把Unicode编码65转换成字符'A'
ord()将一个字符转换成对应的Unicode编码。code = ord('A')  # 把字符'A'转换成Unicode编码65
hex()

将一个整数转换成十六进制字符串。hex_str = hex(255)  # 把整数255转换成十六进制字符串'0xff'

oct()

将一个整数转换成八进制字符串。oct_str = oct(255)  # 把整数255转换成八进制字符串'0o377'

bin()

将一个整数转换成二进制字符串。bin_str = bin(255)  # 把整数255转换成二进制字符串'0b11111111'

eval()将字符串str当成有效的表达式来求值并返回计算结果(存在安全风险,应谨慎使用)。
result = eval("3 + 5")  # 把字符串"3 + 5"当成表达式求值,结果是8

函数

 

函数定义

函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段。python函数定义规则:

def my_max(a,b):   #定义函数用def关键字开头,函数名-》my_max ()定义参数   
    if a>b:        #函数体以:开始并进行缩进
        return a   #结束函数,选择性返回一个值给调用方,不带return相当于返回None
    else: 
        return b
print(my_max(3,4)) #函数名()  函数调用

函数参数

def modify(a): 
    print(hex(id(a))) #0x7ff92c79e328 
    a=10              #传入不可变对象相当于传入新的a,不改变原传入对象的值
    print(hex(id(a))) #0x7ffc560be448
    print(a)          #10
a=1
print(hex(id(a)))     #0x7ffc560be328
modify(a)     
print(a)              #1
def modify(lis):      #可变类型对象的测试,原对象传过来修改也影响了原对象
    lis.append([1,2])
    print('list in func ',lis) #[1, 2, 3, [1, 2]]
    print(hex(id(lis)))   #0x22215e11f00  函数内地址与函数外一样
mylis=[1,2,3]
print(hex(id(mylis)))   #0x22215e11f00
modify(mylis)
print('out funct ',mylis)  #[1, 2, 3, [1, 2]]

参数类型

必需参数必需参数须以正确的顺序传入函数,调用时的数量必须和声明时的一样。
关键字参数

函数调用使用关键字参数来确定传入的参数值,使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

默认参数调用函数时,如果没有传递参数,则会使用默认参数,传递了自然用传递的参数
不定长参数在形参前边加上一个*,这样这个形参将会获取到所有的实参,并将所有的实参保存到一个元组中,*形参只能接收位置参数,而不能接收关键字参数。**形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中。字典的 key 就是参数的名字,字典的 value 就是参数的值。**形参只能有一个,并且必须写在所有参数的最后。
#必须参数
def show(str):
    print(str)
    return
# show() #TypeError: show() missing 1 required positional argument: 'str'
show('2') 

#关键字参数 可以非顺序传参,会根据关键字自组织
def show1(name,age):
    print(name,age)
    return
show1(age=10,name='AC') 
show1(name='AC',age=10)
show1('AC',6)
#默认参数
def show2(name,age=10,add='here'): #与C++一样,一旦有了默认值后面的都要有
    print(name,age,add)
    return
show2(age=2,name='AC')
show2(name='AC')
#不定长参数
def show3(*name):
    print(name,type(name))     #('ac', 'li', 'io')  <class 'tuple'>
show3('ac','li','io') 
def show4(arg,*name):
    print(arg)    
    print(name)
show4(1)    #1 ()
show4(1,2)  # 1  (2,)
show4(1,2,4) #1 (2,4)
def show5(arg,*name,age): #age 必须使用关键字参数
    print(arg,name,age)    
show5(1,2,3,age=5) #1 (2, 3) 5
def show6(arg, name, **a): #** 形参可以接收其他的关键字参数,它会将这些参数统一保存到一个字典中
    print('a =', a, type(a)) #a = {'x': 3, 'y': 4} <class 'dict'>
    print(arg,name)
show6(arg=1,name=2,x=3,y=4)
show6(1,2,x=3,y=4)  #a = {'x': 3, 'y': 4} <class 'dict'>
#强制位参数
def show7(a,b,/,c,d,*,e):
    print(a,b,c,d,e)
show7(1,2,3,d=4,e=5)
#show7(1,b=2,c=3,d=4,e=5) #b 不能使用关键字参数的形式
#show7(1,2,3,4,5) #e 必须使用关键字参数的形式

匿名函数

匿名函数(Anonymous Function)指的是没有具体名字的函数,通常用于临时使用的简单函数。它们通常写得简洁,适合用在需要函数作为参数的场合。lambda 参数列表: 表达式


#匿名函数定义及调用
func=lambda x,y:x+y   #lambda 生成一个函数对象,参数x,y 返回值x+y
func(1,2) #3  函数对象赋给了func, 使用变量调用函数和普通函数无异
#匿名函数作为返回值
def build(x,y):
    return lambda: x*x+y*y
build(2,3)() 

函数举例

1、打乱列表元素

#打乱列表元素
import random
def shuffle_list(ls):
    n=len(ls)
    for i in range(n-1,0,-1):
        j=random.randint(0,i)
        ls[i],ls[j]=ls[j],ls[i]
    return ls
#print(shuffle_list([0,1,2,3,4])) #函数实现
n=[1,2,3,4]
random.shuffle(n) #random自带的洗牌实现
print(n)
#就地改变结构的 Python API 方法通常返回None,而不是修改后的数据结构
print(random.shuffle(n)) #none
#如果您想基于现有列表创建一个 new 随机打乱的列表,其中现有列表保持有序,
# 可以使用random.sample()和输入的完整长度
m=[1,2,3,4]
print(random.sample(m,len(m))) #随机
print(m) #[1,2,3,4]

2、回文判断

def is_palindrome(seque):
    #return seque==seque[::-1] #一行搞定
    left,right=0,len(seque)-1
    while left<right:
        if seque[left]!=seque[right]:
            return False
        left+=1
        right-=1
    return True
print(is_palindrome("rrrr"))

3、检索质数

def is_prime(n):
    if n<=1:
        return False
    for i in range(2,int(n**0.5)+1):
        if n%i==0:
            return False
    return True
def find_p(seque):
    return [num for num in seque if is_prime(num)]
print(find_p(range(20)))

高阶函数

函数式编程:是一种编程范式,一种结构化编程(子程序或者程序代码块),思想在于尽量协程一系列嵌套的函数调用,它的特点是允许把函数作为参数传给另一个函数,还可以返回一个函数,python并非函数式编程语言,但是支持一些函数式编程构建(匿名函数、BIF(filter/map)、偏函数)本质上通过封装对象实现函数式编程。

内置高阶函数map、filter、reduce

# filter函数的使用
def is_odd(x):
    return x % 2 == 1
 
# 使用filter过滤出列表中的奇数
list_of_numbers = [1, 2, 3, 4, 5, 6]
filtered_numbers = filter(is_odd, list_of_numbers)
print(list(filtered_numbers))  # 输出: [1, 3, 5]
result = list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4, 5]))
print(result)  # [2, 4]
 
# map函数的使用
def square(x):
    return x * x
 
# 使用map计算列表中每个数的平方
list_of_numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(square, list_of_numbers))
print(squared_numbers)  # 输出: [1, 4, 9, 16, 25]
result = list(map(lambda x: x * x, [1, 2, 3, 4, 5]))
print(result)  # [1, 4, 9, 16, 25]
 
# reduce函数的使用(Python 3中需要从functools模块导入)
from functools import reduce
 
def add(x, y):
    return x + y
 
# 使用reduce进行求和
list_of_numbers = [1, 2, 3, 4, 5]
result = reduce(add, list_of_numbers)
print(result)  # 输出: 15
result = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result)  # 15

高级特性

切片

sequence[start:stop:step] start:起始索引(包含),默认为 0 stop:结束索引(不包含),默认为序列长度,step:步长(正数从左到右,负数从右到左),默认为 1。

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

表达式结果说明
lst[2:5][2, 3, 4]从索引2到4(不含5)
lst[:4][0, 1, 2, 3]从头开始到索引3
lst[5:][5, 6, 7, 8, 9]从索引5到末尾
lst[::2][0, 2, 4, 6, 8]步长为2,取偶数索引元素
lst[1:7:3][1, 4]从索引1开始,每隔3个取一次,直到索引6
lst[-3:][7, 8, 9]取最后3个元素
lst[::-1][9, 8, 7, 6, 5, 4, 3, 2, 1, 0]反转列表

Python内置了 slice 类型,可以用来创建切片对象s = "abcdefghij" my_slice = slice(2, 8, 2) print(s[my_slice]) # 输出 'ceg'

切片常用于:提取子串、子列表;反转序列;复制序列(lst[:]);跳跃取样(如取偶数索引元素);批量替换序列部分元素(如 lst[2:5] = [20, 30, 40])。

切片的特点:切片不会报索引越界错误,超出范围自动截断;切片返回的是原序列的浅拷贝(对于列表、元组等),修改切片不会影响原序列;字符串是不可变类型,切片返回新字符串。

迭代、迭代器

迭代(Iteration):依次访问集合中的每个元素的过程。可迭代对象(Iterable):实现了 __iter__() 方法或定义了 __getitem__() 方法的对象。常见如列表、元组、字符串、字典、集合等。

迭代器(Iterator):实现了 __next__() 方法的对象,用于逐个返回元素。迭代器本身也是可迭代的。是访问集合元素的一种方式,迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

python中可以直接作用于for循环的数据类型有以下几种:一类是集合数据类型,如list、tuple、dict、set、str等;一类是generator,包括生成器和带yield的generator function。这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。可以使用isinstance()判断一个对象是否是Iterable对象;迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不会后退,迭代器有两个基本的方法:iter() 和 next()。

工作机制:调用可迭代对象的 __iter__() 方法,返回一个迭代器对象;通过迭代器的 __next__() 方法逐个获取元素;当没有元素时,__next__() 抛出 StopIteration 异常,迭代结束。

lst = [10, 20, 30]

# 1. for循环(最常用)
for item in lst:
    print(item)

# 2. 手动使用迭代器
it = iter(lst)
while True:
    try:
        item = next(it)
        print(item)
    except StopIteration:
        break

可迭代对象:必须实现 __iter__() 方法,返回迭代器。迭代器:必须实现 __next__() 方法,返回下一个元素。

自定义迭代器

class CountDown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        self.current -= 1
        return self.current + 1

for num in CountDown(5):
    print(num)

不常用但有用的迭代特性

生成器(Generator)

使用 yield 关键字定义,简化迭代器的创建。支持惰性计算,节省内存

生成器表达式gen = (x*x for x in range(5))  print(next(gen)) # 0  print(next(gen)) # 1

itertools模块

itertools.chain(*iterables):串联多个迭代器

itertools.islice(iterable, start, stop, step):切片迭代器

itertools.cycle(iterable):无限循环迭代

itertools.groupby(iterable, key=None):分组迭代

itertools.compress(data, selectors):根据选择器过滤数据

反向迭代for x in reversed([1, 2, 3]): print(x) # 3, 2, 1

enumerate()

for idx, val in enumerate(['a', 'b', 'c']): print(idx, val)

zip()

for a, b in zip([1, 2], ['x', 'y']): print(a, b)

生成器、生成式

通过列表生成式,可以直接创建一个列表。但是受到内存限制列表容量肯定是有限的。一次性创建大的列表会使用很大的存储空间,在Python中,有可以一边循环一边计算的机制,称为生成器:generator。使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作。

yield是用于生成器generator的一种关键字,与return类似,它可以从函数返回值,但不同的是yield返回值可以在下次函数调用时继续执行,而不是退出函数,他的主要目的是是一个函数变成一个生成器可以逐步迭代处理大数据或流数据不是一次性地占用大量内存。

推导式类型语法示例返回类型
列表生成式

[x**2 for x in range(5)]

even_squares = [x**2 for x in range(10) if x % 2 == 0]
pairs = [(x, y) for x in [1, 2, 3] for y in [3, 1, 4] if x != y]

list
集合生成式{x**2 for x in range(5)}set
字典生成式{x: x**2 for x in range(5)}dict
生成器表达式(x**2 for x in range(5))generator
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a        #没有一次性计算除而是next(f) 每次计算保留,然后下一次next继续
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
    try:
        print(next(f))
    except StopIteration:
        break
def test_yield():
    yield 1
    yield 2
    yield 3
#每次调用next(),生成器函数会在yield处停止,并返回一个值,
#再次调用next(),会从上一个停止的位置继续执行,生成。
gen=test_yield()
print(next(gen))

生成器表达式

#生成器表达式
gen_t=(x*x for x in range(3))
print(next(gen_t))
print(next(gen_t))

双向通信:生成器不仅可以向调用者返回值,还可以从调用者接收值,使用send()方法, 还支持throw()和close方法 

def double_yield():
    try:
        x=yield
        while True:
            x=yield x*2
    except GeneratorExit:
        print("call closed()")
gen=double_yield()
next(gen)
print(gen.send(10))
gen.close()

装饰器

装饰器是一种特殊类型的函数,它可以修改或增强其他函数的功能,而无需更改原始函数的源代码。装饰器本质上是一个接收函数作为参数的函数,它返回一个新的函数或者修改过的原函数。

#装饰器
def decorator(func):
    def wrapper():
        print("Before func_to_decorate called.")
        func()
        print("After func_to_decorate called.")
    return wrapper
@decorator
def func_to_decorate():
    print("Function to decorate.")
func_to_decorate()

装饰器优势

1、装饰器可以非侵入式编程,不改动原函数代码即可添加新功能,符合开放-封闭原则(对外开放,对修改封闭)

2、代码复用于DRY原则,(Don't Repeat Yourself)可以将一些通用的功能(如日志记录、权限检查、缓存。统一异常处理等)提取出来,应用于多个函数或方法,而无需在每个函数中重复编写相同的代码。

3、关注点分离,业务逻辑和横切关注点(日志、权限、缓存)分离

4、动态行为修改,运行时改变函数/类的行为

举例分析流程

import time
def time_if(func):
    print("time_if begin ")  #1 time_if begin
    def wraper(*args,**kwargs):
        print("wraper begin ") #2 wraper begin
        star_time=time.time()
        res=func(*args,**kwargs)
        end_time=time.time()
        elsap_time=end_time-star_time
        #5 funct show_fun took  2.0016 second
        print(f"funct {func.__name__} took {elsap_time: .4f} second")
        return res
    return wraper
@time_if
def show_fun():
    print("show_fun begin") #3 show_fun begin
    time.sleep(2)
    print("show_fun is done") #4 show_fun is done
show_fun()

多个函数中添加记录日志功能,就可以创建日志装饰器

def log_function_call(func):
    def wraper(*args,**kwargs):
        print(f"Calling function: {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} returned: {result}")
        return result
    return wraper
@log_function_call
def add(a,b):
    return a+b
@log_function_call
    multipy(a,b):
    return a*b

权限检查装饰器,需要在多个函数中进行权限检查,可以创建一个权限检查装饰器

def requires_permission(permission):
    def decorator(func):
        def wrapper(*args, **kwargs):
            # 假设我们有一个函数来检查权限
            if not check_user_permission(permission):
                raise PermissionError("You do not have permission to perform this action.")
            return func(*args, **kwargs)
        return wrapper
    return decorator
@requires_permission("admin")
def delete_user(user_id):
    return f"User {user_id} deleted."
@requires_permission("editor")
def edit_post(post_id):
    return f"Post {post_id} edited."
 
# 这里的权限检查逻辑被复用,避免在每个函数中重复编写

缓存装饰器,希望在多个函数中实现结果缓存,可以创建一个缓存装饰器

def cache(func):
    cached_results = {}
    
    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result
    return wrapper
 
@cache
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)
 
print(fibonacci(10))  # 第一次计算
print(fibonacci(10))  # 使用缓存

闭包

闭包(closure)是一个函数和它所引用环境的组合。在Python中闭包通常是指在函数内部定义的函数,该内部函数可以访问外部函数的局部变量,即使外部函数已经返回。闭包的一个常见用途是创建可以记住某些状态的函数。

#闭包
# 默认情况下,内部函数不能直接修改外部函数的局部变量,除非它使用 nonlocal 关键字声明
def outer_function(x):
    print('out_func',x) #2
    def inner_function(y):
        print('inner ',y) #3 当double(3)传入
        return x * y 
    return inner_function
 
double = outer_function(2)
print(double(3))  # 6

偏函数

functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

from functools import partial
def func(a, b, c):
    return a + b + c
# 创建一个新的偏函数,预先绑定a=1和b=2
new_func = partial(func, a=1, b=2)
# 现在可以调用new_func并只提供c的值
result = new_func(c=3)  # 返回 6

内置函数 

内置函数



abs(x): 返回数字的绝对值。    abs(-5)  输出5

divmod(a, b): 返回一个包含商和余数的元组 (a // b, a % b)。print(divmod(10, 3))  # 输出: (3, 1)

pow(x, y[, z]): 返回 x 的 y 次幂,如果提供 z,则返回结果对 z 取模。

print(pow(2, 3))  # 输出: 8           print(pow(2, 3, 3))  # 输出: 2

round(number[, ndigits]): 返回浮点数 number 四舍五入到 ndigits 位。

print(round(3.14159, 2))  # 输出: 3.14

min(iterable, *[, key]): 返回可迭代对象中的最小值。print(min([3, 1, 4, 1, 5]))  # 输出: 1

max(iterable, *[, key]): 返回可迭代对象中的最大值。print(max([3, 1, 4, 1, 5]))  # 输出: 5

sum(iterable[, start]): 返回可迭代对象中所有元素的和,start 是初始值。
print(sum([1, 2, 3, 4]))  # 输出: 10






len(s): 返回对象 s 的长度(元素个数)。   print(len("Hello"))  # 输出: 5

range(start, stop[, step]): 返回一个可迭代的整数序列。list(range(1, 10, 2))  #: [1, 3, 5, 7, 9]

next(iterator[, default]): 返回迭代器的下一个元素,如果没有元素则返回 default。
it = iter([1, 2, 3])  print(next(it))  # 输出: 1

filter(function, iterable): 过滤可迭代对象,返回符合条件的元素。
print(list(filter(lambda x: x > 2, [1, 2, 3, 4])))  # 输出: [3, 4]

map(function, iterable): 对可迭代对象中的每个元素应用函数,返回结果。
print(list(map(lambda x: x * 2, [1, 2, 3])))  # 输出: [2, 4, 6]

sorted(iterable, *, key=None, reverse=False): 返回排序后的列表。
print(sorted([3, 1, 4, 1, 5]))  # 输出: [1, 1, 3, 4, 5]

slice(stop) / slice(start, stop[, step]): 返回一个切片对象,用于切片操作。
s = slice(1, 5, 2)     print(list(range(10))[s])  # 输出: [1, 3]

reversed(seq): 返回一个反向迭代器。print(list(reversed([1, 2, 3, 4])))  # 输出: [4, 3, 2, 1]



chr(i): 返回 Unicode 码点 i 对应的字符。print(chr(97))  # 输出: 'a'

ord(c): 返回字符 c 的 Unicode 码点。    print(ord('a'))  # 输出: 97

str(object): 将对象转换为字符串。         print(str(123))  # 输出: '123'

bool([x]): 将值转换为布尔值,空值为 False,非空值为 True。print(bool(0))  # 输出: False

int(x[, base]): 将字符串或数字转换为整数。  print(int("10"))  # 输出: 10

float(x): 将字符串或数字转换为浮点数。   print(float("3.14"))  # 输出: 3.14

complex(real[, imag]): 创建一个复数。 print(complex(1, 2))  # 输出: (1+2j)

bin(x): 返回整数 x 的二进制字符串表示。print(bin(10))  # 输出: '0b1010'

oct(x): 返回整数 x 的八进制字符串表示。print(oct(10))  # 输出: '0o12'

hex(x): 返回整数 x 的十六进制字符串表示。print(hex(10))  # 输出: '0xa'




dict(): 创建一个字典。my_dict = dict(a=1, b=2)          print(my_dict)  # 输出: {'a': 1, 'b': 2}

list(): 创建一个列表。my_list = list((1, 2, 3))            print(my_list)  # 输出: [1, 2, 3]

set(): 创建一个集合。my_set = set([1, 2, 2, 3])        print(my_set)  # 输出: {1, 2, 3}

tuple(): 创建一个元组。my_tuple = tuple([1, 2, 3])   print(my_tuple)  # 输出: (1, 2, 3)




all(iterable): 如果可迭代对象中的所有元素都为真,返回 True,否则返回 False。

print(all([True, True, False]))  # 输出: False

any(iterable): 如果可迭代对象中至少有一个元素为真,返回 True,否则返回 False。

print(any([False, False, True]))  # 输出: True

id(object): 返回对象的唯一标识符(内存地址)。a = 10   print(id(a))  # 输出: 对象的内存地址

input([prompt]): 从用户输入获取数据,返回字符串。

name = input("请输入你的名字: ")   print(f"你好, {name}!")

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None): 打开一个文件,返回文件对象

with open('example.txt', 'w') as f:
    f.write("Hello, World!")

type(object): 返回对象的类型。   print(type(10))  # 输出: <class 'int'>

print("Hello", "World", sep=", ")  # 输出: Hello, World

print(*objects, sep=' ', end='\n', file=None, flush=False): 打印输出到控制台

模块-包

模块:是一个包含所有你定义的函数和变量的文件,以.py后缀结尾。模块可以被别的程序引入和使用其中的函数功能。

包Package: 即文件夹,传统包里有一个 __init__.py 文件。可以为空文件,但一定要有该文件,它是包的标志性文件,在需要情况下可以在里面进行一些包的初始化工作。

#模块
import math  #导入Python标准库中的math模块
print(math.sqrt(4))
from math import sqrt #也可以导入模块中的特定函数或对象如只导入sqrt函数
print(sqrt(3))
#模块重载 Python解释器会在模块第一次导入时执行模块文件。如果模块文件发生了改变
# 必须先卸载模块,然后再重新导入,以便获取最新的代码。可以使用importlib.reload()
# 函数来卸载并重新导入模块:
# import importlib
# import my_module
#  # 对my_module.py做一些修改
# importlib.reload(my_module)

#包,创建包需要一个名为__init__.py的文件,它可以为空,但其存在表明这个目录
#应被视为一个包。如创建一个名为my_package的包:
#my_package/
#    __init__.py
#    my_module.py
#__init__.py文件可以包含初始化代码和要导入的对象。例如,在my_package/__init__.py
# 中导入my_module中的my_function:

# my_module.py    在my_module.py中,可以定义一个函数
# def my_function():
#     print("Hello from my_package!")
#from my_package.my_module import my_function
#my_function()  # 输出:Hello from my_package!

#包的导入 分为相对导入和绝对导入
#相对导入(以点开头),from .my_module import my_function
# 或绝对导入(直接指定模块或子包的名称) from my_package.my_module import my_function

#包版本管理
#每个包都可以包含一个名为__version__.py的文件,用于指定包的版本。这可以通过
#导入pkg_resources模块来检查

__init__.py 的作用

标识包
在Python2和早期Python3版本中,只有包含 __init__.py 文件的目录才被认定为Python包。虽然Python 3.3以后引入了隐式命名空间包(可以没有 __init__.py),但为了兼容性和明确性,通常仍建议添加它。

初始化包
当你导入包时,__init__.py 中的代码会被执行,可以用来初始化包的环境,比如导入子模块、设置包级变量等。

# package/__init__.py
from . import module1
from .module2 import ClassA, function_b
#这样用户导入包时,可以直接访问 package.module1 或 package.ClassA。

# package/__init__.py
version = "1.0.0"

def info():
    print("This is my package version", version)
#用户可以通过 import package 后访问 package.version 和 package.info()。

控制导入行为
通过在 __init__.py 中定义 __all__ 列表,可以控制 from package import * 时导入哪些模块或变量。

# package/__init__.py
__all__ = ['module1', 'module2']
#这样执行 from package import * 时,只会导入 module1 和 module2。

# package/__init__.py
import logging

logging.basicConfig(level=logging.INFO)
logging.info("Package initialized")
#执行包初始化代码比如设置日志、配置环境变量等
作用说明
标识包让Python识别目录为包
初始化包环境执行包导入时的初始化代码
导入子模块简化用户导入路径
定义包级变量和函数提供包的元信息或工具函数
控制 from package import *通过 __all__ 控制导入内容

您可能感兴趣的与本文相关的镜像

Python3.11

Python3.11

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值