在python中,我们所拥有以下几种非常有用的高级特性能够使我们在编写代码的过程中,使我们的代码量大大减少。
- 切片(Slice)
切片
常用于从某个对象中抽取部分值
的情况,只要条件表达式
得当,可以通过单次
或多次
切片操作实现任意目标值
的切取
。 如果你想尽快知道list(range(1,21))实现原理,可以先观看本章的列表生成器部分。
L = list(range(1,21)) #自定义一个列表,存入有序数列1-20共二十个数
print(L) #打印列表L
print(type(L)) #打印列表类型
print(L[0:5]) #打印列表前五个值即下标为0-4,[0:5]表示从索引0开始,直到索引5结束,但不包括索引3
print(L[:5]) #与上条功能相同,表达式更简便
print(L[17:20]) #打印列表最后三位数字即下标为17,18,19的三位数。[17:20]表示从索引17开始,直到索引20结束,但不包括索引20。
print(L[-3:]) #与上条功能相同,表达式更简便
print(L[:10:5]) #列表的前十个数中,每五个数取一个值
print(L[::5]) #列表的所有数中,每五个数从中取一个
打印为:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
<class 'list'>
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[18, 19, 20]
[18, 19, 20]
[1, 6]
[1, 6, 11, 16]
tuple
也是list
的一种,区别
是tuple不可变
,所以tuple也是可以
使用切片
操作,不过结果
仍是tuple
。字符串
‘ XXX ‘也可以看成一种list
,不过每一个字符
就是一个元素
,所以字符串
也是可以使用切片
操作,不过结果
仍是字符串
。
T = (1,2,3,4,5,6,7,8,9,10) #创建一个tuple
print(T) #打印tuple
print(T[:]) #[:]效果与本身相同
print(T[:3]) #打印tuple前三个值
print(type(T[:])) #打印tuple切片后获取到的数据的数据类型
S = "Python" #创建一个字符串
print(S[:3]) #切片获取前三个值,即组合成的新的字符串
print(type(S[:])) #获取字符串切片后的数据的数据类型
打印为:
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(1, 2, 3)
<class 'tuple'>
Pyt
<class 'str'>
- 迭代(Iteration)
如果给定一个list或tuple等,我们可以通过for循环
进行遍历
,这种遍历
我们叫做迭代
。在Python
中迭代
是通过for...in...
来完成的。 我们判断一个对象是不是迭代对象可以引用 collections.abc 模板下的Iterable。例如:
#导入
from collections.abc import Iterable
L = list(range(5)) #创建数组
print(isinstance(L,Iterable)) #判断数组 L 是否是可迭代对象并打印出来
print(isinstance('abc',Iterable)) #判断 字符串'abc' 是否是可迭代对象并打印出来
# 遍历数组L,并打印
for value in L:
print(value)
打印为:
True
True
0
1
2
3
4
对于dict
我们也可以进行迭代
,但由于键值对
我们默认
只迭代key
,如果想要迭代value
我们可以使用dict.values()
,如果想要同时
迭代key
和value
我们则需要使用dict.items()
。
d = {"Join": "蛋糕", "Tom": "雪糕"} #创建dict
print("-----只迭代key-----")
for key in d:
print(key)
print("-----只迭代value-----")
for value in d.values():
print(value)
print("-----同时迭代key和value-----")
for k,v in d.items():
print("key : " + k , "\tvalue:" , v)
打印结果为:
-----只迭代key-----
Join
Tom
-----只迭代value-----
蛋糕
雪糕
-----同时迭代key和value-----
key : Join value: 蛋糕
key : Tom value: 雪糕
像我们刚刚迭代dict
,能够同时
获取两个值
,其实,元素对
返回的是一个元组数据
,所以可以我们拆分
成多个变量
去接,方便我们同时引用多个变量
。
for x, y in [(1, 'a'), (2, 'b'), (3, 'c')]:
print('x =', x, 'y =', y)
打印为:
x = 1 y = a
x = 2 y = b
x = 3 y = c
如果我们想要获取
到迭代对象的下标
,我们可以使用Python
内置的enumerate
函数把它变成索引-元素对
,这样我们就可以同时迭代索引
和元素对
本身。
#迭代dict,默认只迭代key值
for i, key in enumerate({"Join": "蛋糕", "Tom": "雪糕"}):
print('i =', i, 'key =', key)
打印为:
i = 0 key = Join
i = 1 key = Tom
- 列表生成式
列表生成式
即List Comprehensions
,是Python
内置的非常简单却强大的可以用来创建list
的生成式
。 例如:
L1 = list(range(1,10))
L2 = list(range(0,10))
L3 = list(range(10)) #等同第二个
print(L1)
print(L2)
print(L3)
打印为:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
当然列表生成器还有更多略微复杂的操作,如果要生成[1×1, 2×2, 3×3, …, 10×10]怎么做?方法一是循环,方法二则是我们使用列表生成器代替循环,例如:
L1 = []
# 方法一:使用for循环,每次循环都在列表结尾进行追加
for x in range(1,11):
L1.append(x * x)
#方法二:列表生成器
L2 = [a * a for a in range(1,11)]
print(L1)
print(L2)
打印为:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
我们甚至可以进行更多操作:
# 创建成功列表后在判断进行取出源列表内的所有偶数集
L1 = [x * x for x in range(1,11) if x % 2 == 0]
#有if那么我们肯定就有else语句
L2 = [x * x if x % 2 == 0 else 0 for x in range(1,11)]
#从第一个字符串中挨个取出作为x,从第二个字符串中挨个取出作为y,并进行组合排列
L3 = [x + y for x in '唱跳R' for y in '吃喝玩']
#把list中的所有字符串都变成小写
L4 = ['Boy','Girl','IBM']
L4 = [s.lower() for s in L4]
print(L1)
print(L2)
print(L3)
print(L4)
打印为:
[4, 16, 36, 64, 100]
[0, 4, 0, 16, 0, 36, 0, 64, 0, 100]
['唱吃', '唱喝', '唱玩', '跳吃', '跳喝', '跳玩', 'R吃', 'R喝', 'R玩']
['boy', 'girl', 'ibm']
- 生成器
- 什么是生成器 在
Python
中,一边循环
一边计算
的机制,称为生成器
:generator
。并且生成器仅仅保存
了一套生成数值的算法
,并且没有
让这个算法现在就开始执行
,而是
我什么时候调它
,它什么时候
开始计算
一个新的值
, - 为什么要有生成器 如果
列表元素
按照某种算法
推算出来,那我们就可以在循环的过程中
不断推算出
后续的元素
,这样就不必
创建完整的list
,从而节省
大量的空间
。如果我们想要得到庞大的数据
,又想让它占用空间少
,那我们最好的方法就是使用生成器
。 并给你返回。
我们创建一个generator只需要把列表生成式的[]改为()就可以。
g = (x for x in range(1,11)) #创建一个generator
print(g) #打印
print(type(g)) #打印其类型
print("-----使用next()获取generator的每一个值-----")
#打印g的元素,next()只可以返回获得generator的下一个返回值,所以我们如果一直使用next()函数获取generator的每一个值会非常麻烦也不现实
print(next(g))
print(next(g))
print(next(g))
print("------使用for循环获取generator的每一个值-----")
for i in g:
print(i)
打印结果为:
<generator object <genexpr> at 0x10fd64750>
<class 'generator'>
-----使用next()获取generator的每一个值-----
1
2
3
------使用for循环获取generator的每一个值-----
4
5
6
7
8
9
10
如果算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
f = fib(5)
print(f)
打印为:
<generator object fib at 0x10353a750>
如果一个函数
中包含yield
关键字,那么这个函数
就不再是
一个普通函数,而
是一个generator
。generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回
,再次执行
时从
上次返回的yield语句
处继续执行
- 迭代器
- 生成器都是迭代器,而基本数据集合不属于迭代器,区别在于能不能使用next(), 可以用iter([])来讲基本集合类型转化为迭代器
- 迭代器对象无法预知集合的长度,是一个在调用的时候才能获取到对应位置对象的惰性计算对象,是一种流的形式
- Python的for循环本质上就是通过不断调用next()函数实现的,
- Iterable 迭代类型 Iterator 迭代器