在Python中,切片(slice)是对序列型对象(如list, string, tuple)的一种高级索引方法。普通索引只取出序列中一个下标对应的元素,而切片取出序列中一个范围对应的元素。
简单切片指的是这样的切片形式:a[start:stop],其行为是得到下标在这样一个前闭后开区间范围内的元素,其中start和stop为负数时,简单看作是负数下标对应的位置即可:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[2:3])
# [2]
print(a[5:9])
# [5, 6, 7, 8]
print(a[5:-1])
# [5, 6, 7, 8]
print(a[-5:9])
# [5, 6, 7, 8]
print(a[-5:-1])
# [5, 6, 7, 8]
两个比较特殊的情况:超出有效索引范围和缺省。
当start或stop超出上文提到的有效索引范围时,切片操作不会抛出异常,而是进行截断。
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[-100:5])
# [0, 1, 2, 3, 4]
print(a[5:100])
# [5, 6, 7, 8, 9]
print(a[-100:100])
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[100:1000])
# []
另外,如果start的位置比stop还靠后怎么办?Python还是不会抛出异常,而是直接返回空序列:
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[6:5])
# []
start和stop都是可以缺省的,在缺省的情况下,Python的行为是尽可能取最大区间,具体来说:
按照扩充索引范围的观点,start的缺省值是无穷小(),stop的缺省值是无穷大()。
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[:5])
# [0, 1, 2, 3, 4]
print(a[5:])
# [5, 6, 7, 8, 9]
print(a[100:])
# []
扩展切片指的是这样的切片形式:a[start:stop:step],其中step是一个非零整数,即比简单切片多了调整步长的功能,此时切片的行为可概括为:从start对应的位置出发,以step为步长索引序列,直至越过stop对应的位置,且不包括stop本身。事实上,简单切片就是step=1的扩展切片的特殊情况。需要详细解释的是step分别为正数和负数的两种情况。
当step为正数时,切片行为很容易理解,start和stop的截断和缺省规则也与简单切片完全一致:
# step为正数
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[0:6:2])
# [0, 2, 4]
print(a[::2])
# [0, 2, 4, 6, 8]
print(a[:-2:2])
# [0, 2, 4, 6]
print(a[4::2])
# [4, 6, 8]
当step为负数时,切片将其解释为从start出发以步长|step|逆序索引序列,此时,start和stop的截断依然遵循前述规则,但缺省发生一点变化,因为我们说过,在缺省的情况下,Python的行为是尽可能取最大区间,此时访问是逆序的,start应尽量取大,stop应尽量取小,才能保证区间最大,因此:
按照扩充索引范围的观点,start的缺省值是无穷大(),stop的缺省值是无穷小()
# step为负数
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[5::-1])
# [5, 4, 3, 2, 1, 0]
print(a[:4:-2])
# [9, 7, 5]
print(a[::-1])
# [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
列表生成式的结构是在一个中括号里包含一个表达式,然后是一个for语句,然后是0个或多个for或者if语句。列表表达式可以是任意的,意思是你可以在列表中放入任意类型的对象。返回结果将是一个新的列表,在这个以if和for语句为上下文的表达式运行完成之后产生。
一般方法:
l1 = []
for i in range(1,11):
l1.append(i*i)
print(l1)
列表生成式:
l2 = [i*i for i in range(1,11)]
print(l2)
一般形式:
l3 = []
for i in range(1,11):
if i%2 != 0:
l3.append(i*i)
print(l3)
列表生成式
l4 = [i*i for i in range(1,11) if i%2 != 0]
print(l4)
列表生成式
l5 = [i+j for i in 'ABC' for j in '123']
print(l5)
一般模式
l6 = []
for i in 'ABC':
for j in '123':
l6.append(i+j)
print(l6)
正则表达式是一种用来描述字符串模式的文本。它由一些特殊字符和普通字符组成,可以用来匹配特定的字符串模式。例如,可以使用正则表达式匹配所有的电子邮件地址、所有的URL、所有的电话号码等。正则表达式不仅可以用来匹配字符串,还可以用来替换字符串,或者提取字符串中的某些部分。
在Python中,正则表达式模块为re,它提供了一组函数和类,用于操作正则表达式。在使用re模块之前,需要先导入re模块,可以使用以下代码进行导入:
import re
正则表达式语法包括一些特殊字符和普通字符,它们组合起来形成了正则表达式模式。以下是一些常用的正则表达式语法:
特殊字符类
re模块提供了一组函数,用于操作正则表达式,常用的函数包括:
参数说明:
下面通过一些示例来说明Python中正则表达式的使用。
re.match()方法用于从字符串的开头开始匹配模式,如果匹配成功,则返回一个匹配对象;否则返回None。
import re
pattern = r"hello"
string = "hello world"
result = re.match(pattern, string)
if result:
print("Match found!")
else:
print("No match")
re.search()方法用于在字符串中搜索匹配模式,如果找到任意位置的匹配,则返回一个匹配对象;否则返回None。
import re
pattern = r"world"
string = "hello world"
result = re.search(pattern, string)
if result:
print("Match found!")
else:
print("No match")
re.findall()方法用于在字符串中搜索所有匹配模式的子串,并将它们作为列表返回。
import re
pattern = r"\d+"
string = "I have 10 apples and 20 oranges."
result = re.findall(pattern, string)
print(result) # Output: ['10', '20']
re.sub()方法用于在字符串中搜索匹配模式的子串,并将其替换为指定的字符串。
import re
pattern = r"apple"
string = "I have an apple."
result = re.sub(pattern, "banana", string)
print(result) # Output: "I have an banana."
定义函数的语法格式
def 函数名(形参列表):
#可执行语句
return 返回值
# 函数定义
def myfunc(arg1, arg2, arg3=None):
'''
This is a example for python documentation.
这是一个为python函数提供文档的例子。
arg1: 第一个参数的说明
arg2: 第二个参数的说明
arg3: 第三个参数的说明(这个参数有默认值)
v1, v2, v3: 返回值的说明
'''
v1 = arg1 + arg2
v2 = arg1 * arg2
if arg3 is None:
v3 = arg1 + arg2
else:
v3 = arg1 + arg2 + arg3
return v1, v2, v3
# 函数调用
v1, v2, v3 = myfunc(5, 3, arg3=4)
print(v1, v2, v3) #8 15 12
# 使用arg3的默认值调用函数
v1, v2, v3 = myfunc(5, 3)
print(v1, v2, v3) #8 15 8
# 忽略一个返回值
v1, v2, _ = myfunc(5, 3)
print(v1, v2, v3) #8 15 8
# 看看返回值是元组tuple,在返回的过程中被自动解包
print(type(myfunc(5,3))) #
#举一个小栗子,计算纸箱子的体积
def cube_volume(length, width, height = 0.25):
'''
计算纸箱子的体积(单位:m)
length: 长; width: 宽
height: 高(默认参数0.25)
v: 返回值,纸箱的体积,单位m**3
'''
if length <= 0:
print('length must larger than 0!')
return 0
if width <= 0:
print('width must larger than 0!')
return 0
if height <= 0:
print('height must larger than 0!')
return 0
v = length*width*height
print('length = %.2f; width = %.2f; height = %.2f; cube volume = %.2f' % \
(length, width, height, v))
return v
# 使用位置参数调用
v = cube_volume(1, 2, 3)
# 使用关键字参数调用
v = cube_volume(width = 1, height = 2, length = 3)
# 位置参数和关键字参数混用
v = cube_volume(1, height = 2, width = 3)
# 关键字参数在位置参数之前会报错
# v = cube_volume(width = 1, 2, 3)
经典递归应用:斐波拉契数列
# 斐波那契数列(Fibonacci sequence)
def Fibonacci(n):
''' Fibonacci sequence
f(0)=1, f(1) = 1, f(n) = f(n-1)+f(n-2)
'''
if n == 0 or n == 1:
return 1
else:
return Fibonacci(n-1) + Fibonacci(n-2)
# 测试一下,注意n不要设的太大,python的递归效率是比较低的,太大会死机
print(Fibonacci(5))
# 斐波那契数列,前20位
print('Fibonacci sequence:')
for i in range(20):
print('%d: %d' % (i,Fibonacci(i)))
在刚入门python时,模块化编程、模块、类库等术语常常并不容易理清。尤其是Modules(模块)和Packages(包),在import引用时很容易混淆出错。
实际上,Python中的函数(Function)、类(Class)、模块(Module)、包库(Package),都是为了实现模块化引用,让程序的组织更清晰有条理。
通常,函数、变量、类存储在被称为模块(Module)的.py文件中,一组模块文件又组成了包(Package)。
将函数、变量、类存储在存储在独立的.py文件中,可隐藏代码实现的细节,将不同代码块重新组织,与主程序分离,简化主程序的逻辑,提高主程序的可读性。
有了包和模块文件,可以在其他不同程序中进行复用,还可以使用其他人开发的第三方依赖库。
import random
print(random.random())
print(random.randint(3,100))
rl = [2,1,3,4,2,2,1,4,5,6,2,5,2,1]
print(random.choice(rl))
print(random.uniform(1,2))
import os
print(os.getcwd())
print(os.path.abspath(os.getcwd()))
print(os.path.split(os.getcwd()))
import time
print(time.time())
print(time.localtime())
print("---start---")
time.sleep(2) # 休眠2秒
print("-- end---")
以requests为例:
对于第三方模块需要先进行安装操作
pip install requests
安装好对应包后再项目中进行导入
import requests
导入对应的包后即可在项目中使用包中的对应函数方法
response = requests.get('http://httpbin.org/get')
print(response.text)
将返回值以json形式打印
import requests
import json
response = requests.get("http://httpbin.org/get")
print(type(response.text))
print(response.json())
print(json.loads(response.text))
print(type(response.json()))
Modules模块是包含 Python 定义和语句的文件。以.py为后缀的文件名就是模块名称。
我们创建了一个fibo.py文件,文件内容为:
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
这里fibo.py就是一个模块,fib、fib2是fibo模块中的函数。
如果我们想要在其他程序中使用fibo模块,可以有以下三种方式导入:
①导入整个模块
#import module_name
import fibo
可使用下面的语法来使用其中任何一个函数:
#module_name.func()
fibo.fib(10)
⭕ 注意:这里模块名+句点不可省略。
②导入模块中的特定函数
#from module_name import function_name
from fibo import fib, fib2
fib(10)
若使用这种语法,调用函数时就无需使用模块名+句点。
因为在import语句中已经显式地导入了函数fib和fib2,因此调用它时只需指定其名称。
③导入模块中的所有函数
#from module_name import *
from fibo import *
fib(20)
这种方式会导入除可下划线 (__)开头的名称以外的所有函数。
⭕ 注意:在大多数情况下,通常不推荐*这种用法,因为它可能会在解释器中引入了一组未知的名称,而且通常会导致代码可读性变差。
给导入的模块一个别名
# import module as m
import numpy as np
a = np.arange(100)
利用as给导入模块一个别名,简化代码中的调用写法。
如果我们想单独测试下模块,可以在模块中添加以下代码,就可以既用作脚本,也可用作可导入模块:
if __name__ == "__main__":
fib(10)
这里的.可以访问同级目录下的包(Package)或者模块(Module)。
这里的..可以访问上一级目录下的包(Package)或者模块(Module)。
描述
sum() 方法对序列进行求和计算。
语法
以下是 sum() 方法的语法:
sum(iterable[, start])
参数
返回值
返回计算结果。
实例
print(sum([0,1,2]))
print(sum((2, 3, 4), 1)) # 元组计算总和后再加 1
print(sum([0,1,2,3,4], 2)) # 列表计算总和后再加 2
描述
sorted() 函数对所有可迭代的对象进行排序操作。
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
语法
sorted 语法:
sorted(iterable, key=None, reverse=False)
参数说明:
iterable – 可迭代对象。
key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)。
返回值
返回重新排序的列表。
# b) 排序函数sorted
a = [5, 7, 6, 3, 4, 1, 2]
b = sorted(a) # 保留原列表
print(a)
# [5, 7, 6, 3, 4, 1, 2]
print(b)
# [1, 2, 3, 4, 5, 6, 7]
L = [('f', 2), ('a', 1), ('c', 3), ('d', 4)]
L1 = sorted(L, key=lambda x: x[1]) # 利用key
L2 = sorted(L, key=lambda x: x[0]) # 利用key
print(L1)
# [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
print(L2)
# [('a', 1), ('c', 3), ('d', 4), ('f', 2)]
students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
res1 = sorted(students, key=lambda s: s[2]) # 按年龄排序
print(res1)
# [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
res2 = sorted(students, key=lambda s: s[2], reverse=True) # 按降序
print(res2)
# [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
res3 = sorted(students, key=lambda s: (s[1],s[2])) # 按分类排序,分类相同按年龄
print(res3)
# [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
描述
filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。
语法
以下是 filter() 方法的语法:
filter(function, iterable)
参数
返回值
返回一个迭代器对象
实例
过滤出列表中的所有奇数:
def is_odd(n):
return n % 2 == 1
tmplist = filter(is_odd, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
newlist = list(tmplist)
print(newlist)
# [1, 3, 5, 7, 9]
过滤出1~100中平方根是整数的数:
import math
def is_sqr(x):
return math.sqrt(x) % 1 == 0
tmplist = filter(is_sqr, range(1, 101))
newlist = list(tmplist)
print(newlist)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
描述
max() 方法返回给定参数的最大值,参数可以为序列。
语法
以下是 max() 方法的语法:
max( x, y, z, .... )
参数
返回值
返回给定参数的最大值。
实例
以下展示了使用 max() 方法的实例:
print ("max(80, 100, 1000) : ", max(80, 100, 1000))
print ("max(-20, 100, 400) : ", max(-20, 100, 400))
print ("max(-80, -20, -10) : ", max(-80, -20, -10))
print ("max(0, 100, -400) : ", max(0, 100, -400))
以上实例运行后输出结果为:
max(80, 100, 1000) : 1000
max(-20, 100, 400) : 400
max(-80, -20, -10) : -10
max(0, 100, -400) : 100
描述
min() 方法返回给定参数的最小值,参数可以为序列。
语法
以下是 min() 方法的语法:
min( x, y, z, .... )
参数
返回值
返回给定参数的最小值。
实例
以下展示了使用 min() 方法的实例:
print ("min(80, 100, 1000) : ", min(80, 100, 1000))
print ("min(-20, 100, 400) : ", min(-20, 100, 400))
print ("min(-80, -20, -10) : ", min(-80, -20, -10))
print ("min(0, 100, -400) : ", min(0, 100, -400))
以上实例运行后输出结果为:
min(80, 100, 1000) : 80
min(-20, 100, 400) : -20
min(-80, -20, -10) : -80
min(0, 100, -400) : -400
描述
abs() 函数返回数字的绝对值。
语法
以下是 abs() 方法的语法:
abs( x )
参数
返回值
函数返回 x(数字)的绝对值,如果参数是一个复数,则返回它的大小。
实例
以下展示了使用 abs() 方法的实例:
print ("abs(-40) : ", abs(-40))
print ("abs(100.10) : ", abs(100.10))
以上实例运行后输出结果为:
abs(-40) : 40
abs(100.10) : 100.1
描述
map() 函数会根据提供的函数对指定序列做映射。
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
语法
以下是 map() 方法的语法:
map(function, iterable, ...)
参数
返回值
返回一个迭代器。
实例
以下实例展示了 map() 的使用方法:
def square(x) : # 计算平方数
return x ** 2
map_return = map(square, [1,2,3,4,5]) # 计算列表各个元素的平方
print(map_return)
#
map_return_list = list(map(square, [1,2,3,4,5])) # 使用 list() 转换为列表
print(map_return_list)
# [1, 4, 9, 16, 25]
Python3 错误和异常
实例
使用 try…except…finally 语句
print("===== 错误处理 =====")
# 不加错误处理时:
a = 3
b = 0
# 这里会报除零错误
# print(a / b)
# 采用错误处理
try:
print(a / b)
except ZeroDivisionError as ex1: # 捕获除零错误
print("除零错误!", ex1)
finally:
print("程序结束")
print("===== 错误处理2 ======")
# 同时处理多种错误
c = 5
d = "ss"
try:
print(c / d)
except ZeroDivisionError as ex1:
print("除零错误!", ex1)
except TypeError as ex2:
print("类型不对!必须都为数值!", ex2)
except Exception as ex3:
print("未知错误!", ex3)
finally:
print("程序结束!")
# 为什么有len(a)和省略len(a)结果会不一样?
a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a[0::-1])
# [0]
print(a[0:len(a):-1])
# []
当step为负数时,切片将其解释为从start出发以步长|step|逆序索引序列,此时,start和stop的截断依然遵循前述规则,但缺省发生一点变化,因为我们说过,在缺省的情况下,Python的行为是尽可能取最大区间,此时访问是逆序的,start应尽量取大,stop应尽量取小,才能保证区间最大,因此:
按照扩充索引范围的观点,start的缺省值是无穷大(),stop的缺省值是无穷小()
方法一:使用列表生成式,计算圆的面积要用到圆周率参数,需要导入math模块:
import math
print([math.pi * r * r for r in range(2,11,2)])
方法二:定义一个求圆面积的函数,然后在列表生成式中直接调用函数,从而求出序列中符合条件的半径的面积:
def square(r):
res = math.pi * r *r
return res
print([square(r) for r in range(2,11,2)])
手机号码由11位数字组成,通常以1开头。使用正则表达式可以匹配符合这种模式的手机号码。以下是一个匹配手机号码的正则表达式:
pattern = r'^1\d{10}$'
其中,^表示字符串的开始位置,1表示必须以1开头,\d表示匹配任意一个数字,{10}表示匹配前一个字符10次,$表示字符串的结束位置。可以使用re.match函数来匹配手机号码:
import re
pattern = r'^1\d{10}$'
string = '12312345678'
match = re.match(pattern, string)
if match:
print('匹配成功')
else:
print('匹配失败')
输出结果为:
匹配成功
邮箱地址通常包含@符号和.符号,使用正则表达式可以匹配符合这种模式的邮箱地址。以下是一个匹配邮箱地址的正则表达式:
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
其中,[a-zA-Z0-9._%±]表示匹配任意一个字母、数字、下划线、点、百分号、加号、减号,
+表示匹配前一个字符1次或多次,@表示匹配@符号,[a-zA-Z0-9.-]表示匹配任意一个字母、数字、点、减号,.[a-zA-Z]{2,}表示匹配.符号和至少两个字母的组合。可以使用re.match函数来匹配邮箱地址:
import re
pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
string = '[email protected]'
match = re.match(pattern, string)
if match:
print('匹配成功')
else:
print('匹配失败')
输出结果为:
匹配成功
使用正则表达式可以替换字符串中符合特定模式的部分。以下是一个替换字符串的示例:
import re
pattern = r'\d+'
string = 'a1b2c3d4'
replacement = 'X'
new_string = re.sub(pattern, replacement, string)
print(new_string)
输出结果为:
aXbXcXdX
在上面的示例中,\d+表示匹配任意一个数字,re.sub函数将字符串中所有匹配到的数字替换为X。
[Python]切片完全指南(语法篇)
python——列表生成式
【全文干货】python—函数详解(值得收藏的学习手册)
python中requests库使用方法详解
详解Python模块化——模块(Modules)和包(Packages)
Python sorted()函数的高级使用(多条件)
python 生成器 generator 详解
玩转Python正则表达式:实用教程带你快速入门
Python正则表达式入门
Python3 正则表达式