7. Python的内置函数

更新 發佈閱讀 52 分鐘
raw-image

Hi,大家好。我是茶桁。

讲完了基础函数和高阶函数之后,我们这一节来研究下Python的内置函数,看看Python在安装完毕之后的解释器里,到底都预先给我们提供好了哪些可用的函数。

本节内容着重介绍一些常用函数,并且会做一些应用上的示例。当然,对于Python的内置函数,我们还可以查询官方文档,我这节参照的为3.10版本文档

range()函数

这几节课中,我们频繁使用并且着重介绍过这个函数,那我们就从它开始介绍吧。

一般我们需要遍历一个数值序列的时候,range()函数就会派上用场,它生成算数级数。

'''
range() 函数
功能: 能够生成一个置顶的数值序列
参数:
start: 开始的值,默认为0
stop: 结束的值
[, step]: 可选,步进值, 默认为1
返回值: 可迭代的对象,数字序列
'''
range(start, stop, [, step])

让我们来看一下:

res = range(10)
print(res, type(res))

-----------------------------
range(0, 10) <class 'range'>

可以看到这其实就是一个range的类,其实在我们Python中,任何数据都是一个对象而已。

来看案例:

# range函数的使用方式
res = range(11)
print(list(res))

-----------------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

当我们的range内只写一个参数时,这个参数就是stop值,也就是从start的默认值0开始到输入的参数值(stop)之前为止,比如这段代码中,stop会结束到11之前,也就是10

我们在这段代码中,将range的内容转化成一个list并打印了出来。当然,我们也可以使用循环,依次去除range内的内容:

for i in res:
print(i, end=" ")

-----------------------------
0 1 2 3 4 5 6 7 8 9 10

记得上节课我们提到过,range()是不支持next()函数的,不过如果我们将其转成迭代器,就可以使用next()函数调用:

res = iter(range(11))
print(next(res))
print(next(res))
print(list(res))

-----------------------------
0
1
[2, 3, 4, 5, 6, 7, 8, 9, 10]

可以看到,使用iter转成迭代器之后,可以正常使用next()函数,并且我们再次查看res的内容,0,1已经被拿走,只将剩余内容转化为list打印了出来。

当我们在range中添加两个参数的时候,start就是第一个参数,第二个参数就是stop值。

# 添加两个参数
for i in range(5, 10):
print(i, end=" ")

-----------------------------
5 6 7 8 9

当我们输入三个参数的时候,第一个参数为start, 第二个参数为stop, 第三个参数就是[, step], 比如:

# 添加三个参数
for i in range(1, 10, 3):
print(i, end=" ")

-----------------------------
1 4 7

这段代码的含义就是从1开始, 以3为步进来提取数字,并打印出来,一直到10之前的数字为止。

如果不太理解步进值的可以执行数一遍就理解了,比如我们从1开始顺序往后数3个数,那就是2、3、4,数到了4, 再继续往后数3个数,就是5、6、7,数到了7。再继续往后就是8、9、10。但是,我们代码中的stop值为10,所以到9就结束了,也就是说,我们这段代码就只取出了1, 4, 7三个值。

三种参数值的情况我们都了解之后我们可以思考下,难道我们只能选择顺序取值吗?其实不然,我们还可以倒叙取值,聪明的小伙伴可能想到了,调换一下startstop值不就可以了嘛?我们从10开始取值,取到0为止:

for i in range(10, 0):
print(i, end=" ")

执行一下,哎,似乎什么都没打印出来。这又是为什么呢?是不是出BUG了?

其实,什么都没打印出来才是正确的,这是因为,虽然我们给了开始和结束值,但是我们遗忘了一个重要的参数,那就是步进值step,这个值默认可是1,从10开始+1来计数,无论如何也算不到0。所以,我们将步进值改成负数,也就是倒着数了:

for i in range(10, 0, -1):
print(i, end=" ")

-----------------------------
10 9 8 7 6 5 4 3 2 1

至此,我们可以得到结论,是否倒叙取值除了开始和结束值,更重要的是看step是正数还是负数。

res = range(-10,-20,-1) 
# [-10, -11, -12, -13, -14, -15, -16, -17, -18, -19]
res = range(-20,-10)
# [-20, -19, -18, -17, -16, -15, -14, -13, -12, -11]
res = range(-10,10)
# [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

zip()函数

zip() 函数可以接受多个可迭代的对象,然后把每个可迭代对象中的第i隔元素组合在一起,形成一个新的迭代器。

'''
参数: *iterables, 任意个的可迭代对象
返回值: 返回一个元组的迭代器
'''
zip(*iterables)

让我们来直接看示例:

n1 = '1234'
n2 = ['a', 'b', 'c']
n3 = ['A', 'B', 'C', 'D']
# 调用zip函数,合成新的元组迭代器
res = zip(n1, n2, n3)
print(list(res))

-----------------------------
[('1', 'a', 'A'), ('2', 'b', 'B'), ('3', 'c', 'C')]

我知道你们看到这个执行结果会有很多疑问,先别着急,我们先看一下它是否包含迭代器的特性:

for i in res:
print(i)

当你执行这段代码的时候就会发现,似乎什么都没发生。

那到底是怎么回事?我们不用for,让我们再转换一次list之后看看里边有什么:

print(list(res))

-----------------------------
[]

列表居然是空的。是不是瞬间想到了什么?

没错,这个似乎就是迭代器的特性之一,当其中元素被使用之后,会删掉使用过的元素。而我们之前在执行print(list(res))的时候,已经将内部元素都转成list并展现过,所以现在res内的元素都被删掉了。

没事,让我们再重新来定义一次,也就是重新给res内填满元素然后直接for循环一次看看:

n1 = '1234'
n2 = ['a', 'b', 'c']
n3 = ['A', 'B', 'C', 'D']
# 调用zip函数,合成新的元组迭代器
res = zip(n1, n2, n3)

for i in res:
print(i)

-----------------------------
('1', 'a', 'A')
('2', 'b', 'B')
('3', 'c', 'C')

我们可以看到,每次打印i的时候都打印了一个元组,而这个元组就是一个新元素,比如第一行('1', 'a', 'A'), 这整个元组就是一个新元素。

让我们再用next试试(当然我又重新填满了res):

print(next(res))
print(next(res))

-----------------------------
('1', 'a', 'A')
('2', 'b', 'B')

next函数也能正常执行,那可以说明,zip确实组合成了一个新的迭代器。

现在我们返回来再看一遍代码中的n1,n2,n3, 分别是1234[‘a’, 'b', 'c']['A', 'B', 'C', 'D']。最后组成的迭代器对象为:[('1', 'a', 'A'), ('2', 'b', 'B'), ('3', 'c', 'C')]

通过分析可以看出来,zip的工作原理是先分别取可迭代对象的第一个元素组合成一个元组,然后再分别取第二个元素组合成一个元组,依次往后取...

可是n1, n3分别都是四个元素,为什么我们最后只组合成了三个元组?那是因为n2中只包含了三个元素,当在其中找不到第四个元素的时候,就会放弃组合。

来,让我们在看一个示例:

n1 = [1, 2, 3, 4]
n2 = [22, 33, 44, 55]
res = zip(n1, n2)
print(list(res))

-----------------------------
[(1, 22), (2, 33), (3, 44), (4, 55)]

大家看到最后的执行结果有没有觉得很眼熟?可能很多小伙伴一时间想不到,我们来调整一下:

[
(1, 22),
(2, 33),
(3, 44),
(4, 55)
]

记住这个数据结构,我们在后期做数据分析的时候, 当我们做矩阵运算的时候用的非常多。

不知道大家是否都学过高等数学里的线性代数、微积分,包括概率统计。这些在我们之后做数据分析,数据挖掘,包括机器学习、人工智能这些科学运算里面,非常重要的一些数学功底。

不太记得了也没关系,这些我后面将会专门拿几节出来给大家补一下这方面。

让我们继续,zip还有一种应用方式,当其与*运算符结合使用的时候,可以用来拆解列表:

# zip 与 * 运算符相结合使用
x = [1, 2, 3]
y = [4, 5, 6]

print(zip(x, y))
print(*zip(x, y))

-----------------------------
<zip object at 0x107b8d200>
(1, 4) (2, 5) (3, 6)

可以看到,zip是一个迭代器,*zip这生成了组合好的多个元组数据。

比如:

x1 = [1, 2, 3]
y1 = [4, 5, 6]

x2, y2 = zip(*zip(x, y))
print(x2, y2)

-----------------------------
(1, 2, 3) (4, 5, 6)

这样,我们就将两个列表转换成了两个元组。当然,其实我们这样操作还不如直接使用tuple函数来的方便快捷一点。

那下面,我们就看看都有哪些数据类型转换相关的内置函数。

数据类型转换相关的内置函数

这些函数的功能非常简单和单一,属于拿来就用的函数,我们就仅列出来,不多做介绍了。

  • int() 将其它类型数据转为整型
  • float()转为浮点类型
  • bool()转为布尔类型
  • complex()转为复数
  • str()转为字符串类型
  • list 转为列表类型
  • tuple转为元组类型
  • dict 转为字典类型
  • set 转为集合类型

变量相关函数

  • id()获取当前数据的ID标识
  • type()获取当前数据的类型字符串
  • print()数据的打印
  • input()获取输入的数据
  • isinstance()检测是否为指定的数据类型

数学相关函数

abs()获取一个数的绝对值

print(abs(-99.99))

-----------------------------
99.99

sum()求和 从 start 开始自左向右对 iterable 中的项求和并返回总计值

print(sum([1,2,3]))

-----------------------------
6

max() 获取最大值

print(max([1,2,3]))
print(max(99,12,45))

-----------------------------
3
99

min() 获取最小值

print(min([2,1,6,-9]))
print(min(6,7,1,0,-2))

-----------------------------
-9
-2

pow(x, y)幂运算 返回 x 的 y 次幂

print(pow(2,3))

-----------------------------
8

round(x, n) 对x四舍五入,小数点保留n位

print(round(3.1415926))
print(round(3.1415926,2))

-----------------------------
3
3.14

 

round这个函数不是绝对意义上的四舍五入,在取整这个问题是是奇进偶退:

print(round(3.5))
print(round(4.5))

-----------------------------
4
4

进制函数及字符集

bin() 将数值类型转为二进制

print(bin(123)) 

-----------------------------
0b1111011

int() 将二进制转化为整型

print(int(0b1111011))

-----------------------------
123

oct() 转为八进制数

print(oct(123))

-----------------------------
0o173

hex() 转为十六进制数

print(hex(123))

-----------------------------
0x7b

ASCII及字符集

ASCII,全称为美国信息互换标准代码。是一套基于拉丁字母的字符编码,共收录了 128 个字符,用一个字节就可以存储,它等同于国际标准 ISO/IEC 646。它一共有128个支付,最后更新是1986年。

我们要知道的是,ASCII 编码是美国人给自己设计的,他们并没有考虑欧洲那些扩展的拉丁字母,也没有考虑韩语和日语,我大中华几万个汉字更是不可能被重视。计算机也是美国人发明的,起初使用的就是 ASCII 码,只能显示英文字符。各个国家为了让本国公民也能正常使用计算机,开始效仿 ASCII 开发自己的字符编码,例如 ISO/IEC 8859(欧洲字符集)、shift_Jis(日语字符集)、GBK(中文字符集)等。

从65开始到90为止,是大写字母(A ~ Z), 97到122是小写字母(a ~ z),48到57是0 ~ 9。

而我们经常使用的是GB2312-80, GBK和GBK18030以及Unicode字符集。

GB2312-80 是 1980 年制定的中国汉字编码国家标准。共收录 7445 个字符,其中汉字 6763 个。

GBK 于1995年制定 收录了 21003 个汉字。GBK向下与 GB 2312 编码兼容,

GBK18030 2001年的1月正式强制执行,是我国制订的以汉字为主并包含多种我国少数民族文字(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)的超大型中文编码字符集强制性标准,其中收入汉字70000余。

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。

  • 它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
  • UTF-8 以字节为单位对Unicode进行编码。

我们现在写代码的时候基本遵循UTF-8编码为主。

有的时候,我们是需要将字符转为ASCII, 也有对应的方法:

print(ord('a'))

-----------------------------
a

将ASCII转为字符也一样:

print(chr(65))

-----------------------------
A

高阶函数

和上一节课不同,我们现在要讲的高阶函数,是Python解释器里的内置高阶函数。

sorted()

很多时候,我们在处理数据的时候都需要对数据进行排序。不管是以序号,名称还是日期的方式。sorted()就是我们最常用的排序函数:

sorted(iterable, [reverse, key])
‘’‘
运行原理:把可迭代数据里面的元素,一个一个的取出来,放到key这个函数中进行处理,并按照函数中return的结果进行排序,返回一个新的列表
功能:排序
参数:
iterable:可迭代的数据 (容器类型数据,range数据序列,迭代器)
reverse:可选,是否反转,默认为False,不反转, True反转
key:可选, 函数,可以是自定义函数,也可以是内置函数
返回值:排序后的结果
’‘’

我们来看几个示例,首先我们先来看看默认的排序方式:从小到大:

arr = [3,7,1,-9,20,10]
res = sorted(arr)
print(res)

-----------------------------
[-9, 1, 3, 7, 10, 20]

当然,既然我们能从小到大来进行排序,那就可以用从大到小的方式:

arr = [3,7,1,-9,20,10]
print(sorted(arr,reverse=True))

-----------------------------
[20, 10, 7, 3, 1, -9]

现在我们得到了从小到大排序,也得到了从大到小排序。然后我们再来作妖:能不能按照所有数字的绝对值大虾哦进行排序呢?哎,还记得我们刚讲过的数学相关的函数里有一个求绝对值的函数嘛?既然sorted()这个函数里的参数key可以接收函数,那让我们结合在一起试试看:

arr = [3,7,1,-9,20,10]
res = sorted(arr,key=abs)
print(res)

-----------------------------
[1, 3, 7, -9, 10, 20]

果然,我们得到了想要的结果。来分析下内部到底做了什么:

[3,7,1,-9,20,10] # 原始列表
3 7 1 9 20 10 # 求绝对值
1 3 7 9 10 20 # 给绝对值进行排序
1 3 7 -9 10 20 # 转换成原本的值

那现在,我再多尝试一下,我试试看自己定义一个函数:

def func(num):
return num % 2

函数定义好了,让我们尝试使用自定义函数对数据进行排序:

arr = [3,2,4,6,5,7,9]
print(sorted(arr, key = func))

-----------------------------
[2, 4, 6, 3, 5, 7, 9]

看似起结果了。那到底函数内干了些什么呢?让我们在其中多打印一点东西出来,看个明白:

def func(num):
print(num, num % 2, end=" ")
print()
return num % 2

arr = [3,2,4,6,5,7,9]
print(sorted(arr, key = func))

-----------------------------
3 1
2 0
4 0
6 0
5 1
7 1
9 1
[2, 4, 6, 3, 5, 7, 9]

这样我们就很清晰的看到了对原数字和取余结果,在对取余进行排序之后,再在取余的结果上进行默认的从小到大进行排序,就得到了最后的结果[2, 4, 6, 3, 5, 7, 9]

不过,这种功能大多数时候我们基本是临时用一下,特意写一个方法似乎有点多余。还记得咱们之前讲的匿名函数吧?让我们用匿名函数优化一下:

# 用匿名函数优化
arr = [3,2,4,6,5,7,9]
res = sorted(arr, key=lambda num:num%2)
print(res)

-----------------------------
[2, 4, 6, 3, 5, 7, 9]

正是我们所要的结果。

从这就能看出来,高阶函数sorted()key因为能接收自定义函数,所以给了我们很大的可玩空间。小伙伴们还能想到哪些方法,快去做做实验。

map()

这个函数在对传入的可迭代数据中的每一个元素进行处理,然后返回一个新的迭代器:

map(func, *iterables)
'''
功能: 对传入的可迭代数据中的每个元素放入到函数中进行处理,返回一个新的迭代器
参数:
func 函数 自定义函数|内置函数
iterables:可迭代的数据
返回值:迭代器
'''

让我们先来看一个普通的函数:

# 把一个字符串数字的列表转为整型列表
items = ['1', '2', '3', '4']
new_list = []
for i in items:
new_list.append(int(i))

print(new_list)

-----------------------------
[1, 2, 3, 4]

我们将一个内部元素均为字符串的列表,转成了一个整型列表。

不过这个函数看起来似乎还是有些麻烦,让我们再用map试试看:

items = ['1', '2', '3', '4']
res = map(int, items)
print(list(res))

-----------------------------
[1, 2, 3, 4]

看,是不是简便多啦?当然,最后map最后生成的是迭代器而并不是列表,我们还是需要转化一下数据类型。

这段代码中map的处理方式其实非常简单,它将items里的每一个元素用int方法转换成整型,转换完之后形成一个新的迭代器,然后返回。

再让我们看一个示例感受一下, 这次我们将两段对比写在一起:

# 普通方法进行实现
items = [1, 2, 3, 4]
res = []
for i in items:
x = i ** 2
res.append(x)
print(res)

# 使用map函数处理
items = [1, 2, 3, 4]
def func(x):
return x ** 2
res = map(func, items)
print(res, list(res))

-----------------------------
[1, 4, 9, 16]
<map object at 0x107ea5030> [1, 4, 9, 16]

我们看到执行结果完全一样,不过使用map()的方式更简洁,逻辑也更清晰。我们要知道,Python本身是自带幂次方方法的。即便是我们自己来实现,其实我们还可以把代码写的更简洁:

items = [1, 2, 3, 4]
res = map(lambda x:x**2, items)
print(res,list(res))

-----------------------------
<map object at 0x107c98610> [1, 4, 9, 16]

基于map的应用,我们来个小作业吧:

我们现在有这样一个列表:['a','b','c','d']

要求将其转换成:[65,66,67,68]

最后,再给大家留个课后作业, 我给大家两个函数及其功能介绍,大家自己去尝试看看,然后自己琢磨下其用法。

reduce()

reduce(func, iterable)

功能:每一次从 iterable 拿出两个元素,放入到func函数中进行处理,得出一个计算结果,然后把这个计算结果和iterable中的第三个元素,放入到func函数中继续运算,得出的结果和之后的第四个元素,加入到func函数中进行处理,以此类推,直到最后的元素都参与了运算

filter()

filter(func, iterable)

功能:过滤数据,把 iterable 中的每个元素拿到 func 函数中进行处理,如果函数返回True则保留这个数据,返回False则丢弃这个数据。

这两个函数在处理数据上作用都非常大。

好了,下课。大家有问题记得留言。

Hi,大家好。我是茶桁。

讲完了基础函数和高阶函数之后,我们这一节来研究下Python的内置函数,看看Python在安装完毕之后的解释器里,到底都预先给我们提供好了哪些可用的函数。

本节内容着重介绍一些常用函数,并且会做一些应用上的示例。当然,对于Python的内置函数,我们还可以查询官方文档,我这节参照的为3.10版本文档

range()函数

这几节课中,我们频繁使用并且着重介绍过这个函数,那我们就从它开始介绍吧。

一般我们需要遍历一个数值序列的时候,range()函数就会派上用场,它生成算数级数。

'''
range() 函数
功能: 能够生成一个置顶的数值序列
参数:
start: 开始的值,默认为0
stop: 结束的值
[, step]: 可选,步进值, 默认为1
返回值: 可迭代的对象,数字序列
'''
range(start, stop, [, step])

让我们来看一下:

res = range(10)
print(res, type(res))

-----------------------------
range(0, 10) <class 'range'>

可以看到这其实就是一个range的类,其实在我们Python中,任何数据都是一个对象而已。

来看案例:

# range函数的使用方式
res = range(11)
print(list(res))

-----------------------------
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

当我们的range内只写一个参数时,这个参数就是stop值,也就是从start的默认值0开始到输入的参数值(stop)之前为止,比如这段代码中,stop会结束到11之前,也就是10

我们在这段代码中,将range的内容转化成一个list并打印了出来。当然,我们也可以使用循环,依次去除range内的内容:

for i in res:
print(i, end=" ")

-----------------------------
0 1 2 3 4 5 6 7 8 9 10

记得上节课我们提到过,range()是不支持next()函数的,不过如果我们将其转成迭代器,就可以使用next()函数调用:

res = iter(range(11))
print(next(res))
print(next(res))
print(list(res))

-----------------------------
0
1
[2, 3, 4, 5, 6, 7, 8, 9, 10]

可以看到,使用iter转成迭代器之后,可以正常使用next()函数,并且我们再次查看res的内容,0,1已经被拿走,只将剩余内容转化为list打印了出来。

当我们在range中添加两个参数的时候,start就是第一个参数,第二个参数就是stop值。

# 添加两个参数
for i in range(5, 10):
print(i, end=" ")

-----------------------------
5 6 7 8 9

当我们输入三个参数的时候,第一个参数为start, 第二个参数为stop, 第三个参数就是[, step], 比如:

# 添加三个参数
for i in range(1, 10, 3):
print(i, end=" ")

-----------------------------
1 4 7

这段代码的含义就是从1开始, 以3为步进来提取数字,并打印出来,一直到10之前的数字为止。

如果不太理解步进值的可以执行数一遍就理解了,比如我们从1开始顺序往后数3个数,那就是2、3、4,数到了4, 再继续往后数3个数,就是5、6、7,数到了7。再继续往后就是8、9、10。但是,我们代码中的stop值为10,所以到9就结束了,也就是说,我们这段代码就只取出了1, 4, 7三个值。

三种参数值的情况我们都了解之后我们可以思考下,难道我们只能选择顺序取值吗?其实不然,我们还可以倒叙取值,聪明的小伙伴可能想到了,调换一下startstop值不就可以了嘛?我们从10开始取值,取到0为止:

for i in range(10, 0):
print(i, end=" ")

执行一下,哎,似乎什么都没打印出来。这又是为什么呢?是不是出BUG了?

其实,什么都没打印出来才是正确的,这是因为,虽然我们给了开始和结束值,但是我们遗忘了一个重要的参数,那就是步进值step,这个值默认可是1,从10开始+1来计数,无论如何也算不到0。所以,我们将步进值改成负数,也就是倒着数了:

for i in range(10, 0, -1):
print(i, end=" ")

-----------------------------
10 9 8 7 6 5 4 3 2 1

至此,我们可以得到结论,是否倒叙取值除了开始和结束值,更重要的是看step是正数还是负数。

res = range(-10,-20,-1) 
# [-10, -11, -12, -13, -14, -15, -16, -17, -18, -19]
res = range(-20,-10)
# [-20, -19, -18, -17, -16, -15, -14, -13, -12, -11]
res = range(-10,10)
# [-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

zip()函数

zip() 函数可以接受多个可迭代的对象,然后把每个可迭代对象中的第i隔元素组合在一起,形成一个新的迭代器。

'''
参数: *iterables, 任意个的可迭代对象
返回值: 返回一个元组的迭代器
'''
zip(*iterables)

让我们来直接看示例:

n1 = '1234'
n2 = ['a', 'b', 'c']
n3 = ['A', 'B', 'C', 'D']
# 调用zip函数,合成新的元组迭代器
res = zip(n1, n2, n3)
print(list(res))

-----------------------------
[('1', 'a', 'A'), ('2', 'b', 'B'), ('3', 'c', 'C')]

我知道你们看到这个执行结果会有很多疑问,先别着急,我们先看一下它是否包含迭代器的特性:

for i in res:
print(i)

当你执行这段代码的时候就会发现,似乎什么都没发生。

那到底是怎么回事?我们不用for,让我们再转换一次list之后看看里边有什么:

print(list(res))

-----------------------------
[]

列表居然是空的。是不是瞬间想到了什么?

没错,这个似乎就是迭代器的特性之一,当其中元素被使用之后,会删掉使用过的元素。而我们之前在执行print(list(res))的时候,已经将内部元素都转成list并展现过,所以现在res内的元素都被删掉了。

没事,让我们再重新来定义一次,也就是重新给res内填满元素然后直接for循环一次看看:

n1 = '1234'
n2 = ['a', 'b', 'c']
n3 = ['A', 'B', 'C', 'D']
# 调用zip函数,合成新的元组迭代器
res = zip(n1, n2, n3)

for i in res:
print(i)

-----------------------------
('1', 'a', 'A')
('2', 'b', 'B')
('3', 'c', 'C')

我们可以看到,每次打印i的时候都打印了一个元组,而这个元组就是一个新元素,比如第一行('1', 'a', 'A'), 这整个元组就是一个新元素。

让我们再用next试试(当然我又重新填满了res):

print(next(res))
print(next(res))

-----------------------------
('1', 'a', 'A')
('2', 'b', 'B')

next函数也能正常执行,那可以说明,zip确实组合成了一个新的迭代器。

现在我们返回来再看一遍代码中的n1,n2,n3, 分别是1234[‘a’, 'b', 'c']['A', 'B', 'C', 'D']。最后组成的迭代器对象为:[('1', 'a', 'A'), ('2', 'b', 'B'), ('3', 'c', 'C')]

通过分析可以看出来,zip的工作原理是先分别取可迭代对象的第一个元素组合成一个元组,然后再分别取第二个元素组合成一个元组,依次往后取...

可是n1, n3分别都是四个元素,为什么我们最后只组合成了三个元组?那是因为n2中只包含了三个元素,当在其中找不到第四个元素的时候,就会放弃组合。

来,让我们在看一个示例:

n1 = [1, 2, 3, 4]
n2 = [22, 33, 44, 55]
res = zip(n1, n2)
print(list(res))

-----------------------------
[(1, 22), (2, 33), (3, 44), (4, 55)]

大家看到最后的执行结果有没有觉得很眼熟?可能很多小伙伴一时间想不到,我们来调整一下:

[
(1, 22),
(2, 33),
(3, 44),
(4, 55)
]

记住这个数据结构,我们在后期做数据分析的时候, 当我们做矩阵运算的时候用的非常多。

不知道大家是否都学过高等数学里的线性代数、微积分,包括概率统计。这些在我们之后做数据分析,数据挖掘,包括机器学习、人工智能这些科学运算里面,非常重要的一些数学功底。

不太记得了也没关系,这些我后面将会专门拿几节出来给大家补一下这方面。

让我们继续,zip还有一种应用方式,当其与*运算符结合使用的时候,可以用来拆解列表:

# zip 与 * 运算符相结合使用
x = [1, 2, 3]
y = [4, 5, 6]

print(zip(x, y))
print(*zip(x, y))

-----------------------------
<zip object at 0x107b8d200>
(1, 4) (2, 5) (3, 6)

可以看到,zip是一个迭代器,*zip这生成了组合好的多个元组数据。

比如:

x1 = [1, 2, 3]
y1 = [4, 5, 6]

x2, y2 = zip(*zip(x, y))
print(x2, y2)

-----------------------------
(1, 2, 3) (4, 5, 6)

这样,我们就将两个列表转换成了两个元组。当然,其实我们这样操作还不如直接使用tuple函数来的方便快捷一点。

那下面,我们就看看都有哪些数据类型转换相关的内置函数。

数据类型转换相关的内置函数

这些函数的功能非常简单和单一,属于拿来就用的函数,我们就仅列出来,不多做介绍了。

  • int() 将其它类型数据转为整型
  • float()转为浮点类型
  • bool()转为布尔类型
  • complex()转为复数
  • str()转为字符串类型
  • list 转为列表类型
  • tuple转为元组类型
  • dict 转为字典类型
  • set 转为集合类型

变量相关函数

  • id()获取当前数据的ID标识
  • type()获取当前数据的类型字符串
  • print()数据的打印
  • input()获取输入的数据
  • isinstance()检测是否为指定的数据类型

数学相关函数

abs()获取一个数的绝对值

print(abs(-99.99))

-----------------------------
99.99

sum()求和 从 start 开始自左向右对 iterable 中的项求和并返回总计值

print(sum([1,2,3]))

-----------------------------
6

max() 获取最大值

print(max([1,2,3]))
print(max(99,12,45))

-----------------------------
3
99

min() 获取最小值

print(min([2,1,6,-9]))
print(min(6,7,1,0,-2))

-----------------------------
-9
-2

pow(x, y)幂运算 返回 x 的 y 次幂

print(pow(2,3))

-----------------------------
8

round(x, n) 对x四舍五入,小数点保留n位

print(round(3.1415926))
print(round(3.1415926,2))

-----------------------------
3
3.14

 

round这个函数不是绝对意义上的四舍五入,在取整这个问题是是奇进偶退:

print(round(3.5))
print(round(4.5))

-----------------------------
4
4

进制函数及字符集

bin() 将数值类型转为二进制

print(bin(123)) 

-----------------------------
0b1111011

int() 将二进制转化为整型

print(int(0b1111011))

-----------------------------
123

oct() 转为八进制数

print(oct(123))

-----------------------------
0o173

hex() 转为十六进制数

print(hex(123))

-----------------------------
0x7b

ASCII及字符集

ASCII,全称为美国信息互换标准代码。是一套基于拉丁字母的字符编码,共收录了 128 个字符,用一个字节就可以存储,它等同于国际标准 ISO/IEC 646。它一共有128个支付,最后更新是1986年。

我们要知道的是,ASCII 编码是美国人给自己设计的,他们并没有考虑欧洲那些扩展的拉丁字母,也没有考虑韩语和日语,我大中华几万个汉字更是不可能被重视。计算机也是美国人发明的,起初使用的就是 ASCII 码,只能显示英文字符。各个国家为了让本国公民也能正常使用计算机,开始效仿 ASCII 开发自己的字符编码,例如 ISO/IEC 8859(欧洲字符集)、shift_Jis(日语字符集)、GBK(中文字符集)等。

从65开始到90为止,是大写字母(A ~ Z), 97到122是小写字母(a ~ z),48到57是0 ~ 9。

而我们经常使用的是GB2312-80, GBK和GBK18030以及Unicode字符集。

GB2312-80 是 1980 年制定的中国汉字编码国家标准。共收录 7445 个字符,其中汉字 6763 个。

GBK 于1995年制定 收录了 21003 个汉字。GBK向下与 GB 2312 编码兼容,

GBK18030 2001年的1月正式强制执行,是我国制订的以汉字为主并包含多种我国少数民族文字(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)的超大型中文编码字符集强制性标准,其中收入汉字70000余。

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。

  • 它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
  • UTF-8 以字节为单位对Unicode进行编码。

我们现在写代码的时候基本遵循UTF-8编码为主。

有的时候,我们是需要将字符转为ASCII, 也有对应的方法:

print(ord('a'))

-----------------------------
a

将ASCII转为字符也一样:

print(chr(65))

-----------------------------
A

高阶函数

和上一节课不同,我们现在要讲的高阶函数,是Python解释器里的内置高阶函数。

sorted()

很多时候,我们在处理数据的时候都需要对数据进行排序。不管是以序号,名称还是日期的方式。sorted()就是我们最常用的排序函数:

sorted(iterable, [reverse, key])
‘’‘
运行原理:把可迭代数据里面的元素,一个一个的取出来,放到key这个函数中进行处理,并按照函数中return的结果进行排序,返回一个新的列表
功能:排序
参数:
iterable:可迭代的数据 (容器类型数据,range数据序列,迭代器)
reverse:可选,是否反转,默认为False,不反转, True反转
key:可选, 函数,可以是自定义函数,也可以是内置函数
返回值:排序后的结果
’‘’

我们来看几个示例,首先我们先来看看默认的排序方式:从小到大:

arr = [3,7,1,-9,20,10]
res = sorted(arr)
print(res)

-----------------------------
[-9, 1, 3, 7, 10, 20]

当然,既然我们能从小到大来进行排序,那就可以用从大到小的方式:

arr = [3,7,1,-9,20,10]
print(sorted(arr,reverse=True))

-----------------------------
[20, 10, 7, 3, 1, -9]

现在我们得到了从小到大排序,也得到了从大到小排序。然后我们再来作妖:能不能按照所有数字的绝对值大虾哦进行排序呢?哎,还记得我们刚讲过的数学相关的函数里有一个求绝对值的函数嘛?既然sorted()这个函数里的参数key可以接收函数,那让我们结合在一起试试看:

arr = [3,7,1,-9,20,10]
res = sorted(arr,key=abs)
print(res)

-----------------------------
[1, 3, 7, -9, 10, 20]

果然,我们得到了想要的结果。来分析下内部到底做了什么:

[3,7,1,-9,20,10] # 原始列表
3 7 1 9 20 10 # 求绝对值
1 3 7 9 10 20 # 给绝对值进行排序
1 3 7 -9 10 20 # 转换成原本的值

那现在,我再多尝试一下,我试试看自己定义一个函数:

def func(num):
return num % 2

函数定义好了,让我们尝试使用自定义函数对数据进行排序:

arr = [3,2,4,6,5,7,9]
print(sorted(arr, key = func))

-----------------------------
[2, 4, 6, 3, 5, 7, 9]

看似起结果了。那到底函数内干了些什么呢?让我们在其中多打印一点东西出来,看个明白:

def func(num):
print(num, num % 2, end=" ")
print()
return num % 2

arr = [3,2,4,6,5,7,9]
print(sorted(arr, key = func))

-----------------------------
3 1
2 0
4 0
6 0
5 1
7 1
9 1
[2, 4, 6, 3, 5, 7, 9]

这样我们就很清晰的看到了对原数字和取余结果,在对取余进行排序之后,再在取余的结果上进行默认的从小到大进行排序,就得到了最后的结果[2, 4, 6, 3, 5, 7, 9]

不过,这种功能大多数时候我们基本是临时用一下,特意写一个方法似乎有点多余。还记得咱们之前讲的匿名函数吧?让我们用匿名函数优化一下:

# 用匿名函数优化
arr = [3,2,4,6,5,7,9]
res = sorted(arr, key=lambda num:num%2)
print(res)

-----------------------------
[2, 4, 6, 3, 5, 7, 9]

正是我们所要的结果。

从这就能看出来,高阶函数sorted()key因为能接收自定义函数,所以给了我们很大的可玩空间。小伙伴们还能想到哪些方法,快去做做实验。

map()

这个函数在对传入的可迭代数据中的每一个元素进行处理,然后返回一个新的迭代器:

map(func, *iterables)
'''
功能: 对传入的可迭代数据中的每个元素放入到函数中进行处理,返回一个新的迭代器
参数:
func 函数 自定义函数|内置函数
iterables:可迭代的数据
返回值:迭代器
'''

让我们先来看一个普通的函数:

# 把一个字符串数字的列表转为整型列表
items = ['1', '2', '3', '4']
new_list = []
for i in items:
new_list.append(int(i))

print(new_list)

-----------------------------
[1, 2, 3, 4]

我们将一个内部元素均为字符串的列表,转成了一个整型列表。

不过这个函数看起来似乎还是有些麻烦,让我们再用map试试看:

items = ['1', '2', '3', '4']
res = map(int, items)
print(list(res))

-----------------------------
[1, 2, 3, 4]

看,是不是简便多啦?当然,最后map最后生成的是迭代器而并不是列表,我们还是需要转化一下数据类型。

这段代码中map的处理方式其实非常简单,它将items里的每一个元素用int方法转换成整型,转换完之后形成一个新的迭代器,然后返回。

再让我们看一个示例感受一下, 这次我们将两段对比写在一起:

# 普通方法进行实现
items = [1, 2, 3, 4]
res = []
for i in items:
x = i ** 2
res.append(x)
print(res)

# 使用map函数处理
items = [1, 2, 3, 4]
def func(x):
return x ** 2
res = map(func, items)
print(res, list(res))

-----------------------------
[1, 4, 9, 16]
<map object at 0x107ea5030> [1, 4, 9, 16]

我们看到执行结果完全一样,不过使用map()的方式更简洁,逻辑也更清晰。我们要知道,Python本身是自带幂次方方法的。即便是我们自己来实现,其实我们还可以把代码写的更简洁:

items = [1, 2, 3, 4]
res = map(lambda x:x**2, items)
print(res,list(res))

-----------------------------
<map object at 0x107c98610> [1, 4, 9, 16]

基于map的应用,我们来个小作业吧:

我们现在有这样一个列表:['a','b','c','d']

要求将其转换成:[65,66,67,68]

最后,再给大家留个课后作业, 我给大家两个函数及其功能介绍,大家自己去尝试看看,然后自己琢磨下其用法。

reduce(func, iterable)

功能:每一次从 iterable 拿出两个元素,放入到func函数中进行处理,得出一个计算结果,然后把这个计算结果和iterable中的第三个元素,放入到func函数中继续运算,得出的结果和之后的第四个元素,加入到func函数中进行处理,以此类推,直到最后的元素都参与了运算

filter(func, iterable)

功能:过滤数据,把 iterable 中的每个元素拿到 func 函数中进行处理,如果函数返回True则保留这个数据,返回False则丢弃这个数据。

这两个函数在处理数据上作用都非常大。

好了,下课。大家有问题记得留言。

留言
avatar-img
茶桁的沙龍
9會員
62內容數
从基础开始,再到Python,然后是CV、BI、NLP等相关技术。从头到尾详细的教授一边人工智能。
茶桁的沙龍的其他內容
2023/08/22
虽然是最后一节课了,但是本节课的任务却是一点也不轻松。相比较而言,如果你以后从事的是数据治理和分析工作,那么本节课的内容可能会是你在今后工作中用到的最多的内容。我们需要学习行列索引的操作,数据的处理,数据的合并,多层索引,时间序列,数据的分组聚合(重点)。最后,我们会有一个案例的展示。
Thumbnail
2023/08/22
虽然是最后一节课了,但是本节课的任务却是一点也不轻松。相比较而言,如果你以后从事的是数据治理和分析工作,那么本节课的内容可能会是你在今后工作中用到的最多的内容。我们需要学习行列索引的操作,数据的处理,数据的合并,多层索引,时间序列,数据的分组聚合(重点)。最后,我们会有一个案例的展示。
Thumbnail
2023/08/21
Hi,大家好。我是茶桁。 上一节课中,我们学习了matplotlib. 实际上,我们已经进入了数据可视化阶段。 可是在上一节课中,所有的数据都是我们固定写好的,包括两个电影的数据展示的案例(柱状图和直方图),都是我们将数据手动写成了数据列表,然后直接使用。 在我们平时的工作中,不太有那么多的机
Thumbnail
2023/08/21
Hi,大家好。我是茶桁。 上一节课中,我们学习了matplotlib. 实际上,我们已经进入了数据可视化阶段。 可是在上一节课中,所有的数据都是我们固定写好的,包括两个电影的数据展示的案例(柱状图和直方图),都是我们将数据手动写成了数据列表,然后直接使用。 在我们平时的工作中,不太有那么多的机
Thumbnail
2023/08/21
Hi, 大家好。我是茶桁。 在上一节课中,我们结束了Python正式的所有内容,但是咱们的Python课程还未结束。从这节课开始,我们要来学习一下Python的第三方库。 Python的生态非常完善也非常活跃,我们不太可能讲目前所有的第三方库全部都介绍一遍,只介绍几个有影响力并且和处理数据相关的
Thumbnail
2023/08/21
Hi, 大家好。我是茶桁。 在上一节课中,我们结束了Python正式的所有内容,但是咱们的Python课程还未结束。从这节课开始,我们要来学习一下Python的第三方库。 Python的生态非常完善也非常活跃,我们不太可能讲目前所有的第三方库全部都介绍一遍,只介绍几个有影响力并且和处理数据相关的
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
在流程控制中,最常用的就是for loop 或是 while loop 語法了。 最常見的場景就是根據條件判斷式,重複執行特定的指令。 如果要在python寫出類似C/C++ for loop,可以怎麼寫呢? 透過索引去進行迭代 for var in range( start=0, sto
Thumbnail
在流程控制中,最常用的就是for loop 或是 while loop 語法了。 最常見的場景就是根據條件判斷式,重複執行特定的指令。 如果要在python寫出類似C/C++ for loop,可以怎麼寫呢? 透過索引去進行迭代 for var in range( start=0, sto
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
今天要來介紹的是Python中資料型別的函數, 這幾天學習的素材是Youtube上“程式柴大大的Python 6 小時初學者課程”,一步一步帶著大家操作並解,學習中也別忘了要多多練習,練習的部分我是把我學到的東西請Chatgpt幫我出類似的題型並讓我練習。 以下我先寫出一個簡單的code,再加以
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
在Python中,我們可以用def關鍵字定義函數,並透過函數名稱呼叫它。函數參數可以是必填、關鍵字、默認或不定長度的類型。return語句負責結束函數並回傳值。全域變數可以在整個程序中使用,而區域變數只能在特定函數內使用。我們還可以在一個文件中定義函數,然後在另一個文件中呼叫它。
Thumbnail
本文詳細介紹了Python中的各種資料型別,包括整數、字串、清單、元組、集合和字典,並提供了相關的操作範例。此外,還解釋了如何在Python中定義和操作變數,包括如何同時對多個變數進行賦值。
Thumbnail
本文詳細介紹了Python中的各種資料型別,包括整數、字串、清單、元組、集合和字典,並提供了相關的操作範例。此外,還解釋了如何在Python中定義和操作變數,包括如何同時對多個變數進行賦值。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
Python 提供了一系列內建函式,其中一部分涉及數學和數學操作。 以下是一些常用的內建函式和數學相關的函式: 基本數學運算: abs(x): 返回 x 的絕對值。 result = abs(-5) print(result) # 輸出: 5 max(iterable) 和 min(
Thumbnail
Python 提供了一系列內建函式,其中一部分涉及數學和數學操作。 以下是一些常用的內建函式和數學相關的函式: 基本數學運算: abs(x): 返回 x 的絕對值。 result = abs(-5) print(result) # 輸出: 5 max(iterable) 和 min(
Thumbnail
本文介紹了Python中函式引數的*args和**kwargs用法,通過*args處理可變數量的位置引數,通過**kwargs處理可變數量的關鍵字引數。不僅介紹了相應的語法和程式範例,還解釋了它們的順序問題和建議的慣例用法。
Thumbnail
本文介紹了Python中函式引數的*args和**kwargs用法,通過*args處理可變數量的位置引數,通過**kwargs處理可變數量的關鍵字引數。不僅介紹了相應的語法和程式範例,還解釋了它們的順序問題和建議的慣例用法。
Thumbnail
在Python中,數值運算非常直觀,你可以使用標準的數學運算符號進行基本的數值運算。以下是一些基本的數值運算: 進行計算時,按照「先乘除後加減」的規則,並優先計算小括號刮起來的運算式。 print('答案:' ,(1+1)*2) #​答案: 4 復合型態的運算子 指定運算子 = 若是結合算術
Thumbnail
在Python中,數值運算非常直觀,你可以使用標準的數學運算符號進行基本的數值運算。以下是一些基本的數值運算: 進行計算時,按照「先乘除後加減」的規則,並優先計算小括號刮起來的運算式。 print('答案:' ,(1+1)*2) #​答案: 4 復合型態的運算子 指定運算子 = 若是結合算術
Thumbnail
在Python中,有三種變數作用域:全域、區域和封閉。 區域作用域(Local Scope): 在函式內部定義的變數具有區域作用域,它們只能在該函式內部訪問。 例如: def my_function(): local_variable = 10
Thumbnail
在Python中,有三種變數作用域:全域、區域和封閉。 區域作用域(Local Scope): 在函式內部定義的變數具有區域作用域,它們只能在該函式內部訪問。 例如: def my_function(): local_variable = 10
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News