12.Python基础语法---“组”总结与补充
这里如下几方面的补充说明
- 关于切片步长参数
- 列表与字典推导式、元组推导式
- 解包操作
关于切片步长参数
语法:list[start:end:step]
s[i:j:k]
-
如果 i 或 j 为负值,则索引顺序是相对于序列 s 的末尾: 索引号会被替换为 len(s) + i 或 len(s) + j。 但要注意 -0 仍然为 0。
备注:后续的说明都基于这个规则先替换为正值后套用。 -
s 从 i 到 j 的切片被定义为所有满足 i <= k < j 的索引号 k 的项组成的序列。 如果 i 或 j 大于 len(s),则使用 len(s)。 如果 i 被省略或为 None,则使用 0。 如果 j 被省略或为 None,则使用 len(s)。 如果 i 大于等于 j,则切片为空。
-
s 从 i 到 j 步长为 k 的切片被定义为索引号 x = i + nk (n满足 0 <= n < (j-i)/k) 的所有项组成的序列。 换句话说,索引号为 i, i+k, i+2k, i+3*k,以此类推,当达到 j 时停止 (但一定不包括 j)。
当 k 为正值时,如果i 和 j 大于len(s), 将被替代为len(s)。
当 k 为负值时,如果i 和 j 大于len(s) - 1,将被替代为len(s) -1。
如果 i 或 j 被省略或为 None,它们会成为“终止”值 (是哪一端的终止值则取决于 k 的符号)。 请注意,k 不可为零。 如果 k 为 None,则当作 1 处理。
规律总结:
若step>0,表示是从左向右进行切片;此时,start值必须小于end值才会有结果,否者为空;
若step<0,表示是从右向左进行切片;此时,start值必须大于end值才会有结果,否者为空;
上述说明中start,end为同符号
list[::-1]表示从右向左以步长为1进行切片
list[::2]表示从左向右以步长为2进行切片
# 正步长
print("*" * 23)
str_give = '123456789'
print(str_give[::])
# i=None, j=None ==> i=0, j=9
# 123456789
print(str_give[2:7:])
# i=2, j=7
# 34567
print(str_give[-7:-2:])
# i=-7,j=-2;len(s)=9 ==> 索引替换:i=len(s)+i=2, j=len(s)+j=7
# 34567
print(str_give[2::])
# i=2, j=None ==> i=2, j=9
# 3456789
print(str_give[-7::])
# i=-7, j=None ==> 索引替换:i=len(s)+i=2, j=9
# 3456789
print(str_give[:7:])
# i=None, j=7 ==> i=0,j=7
# 1234567
print(str_give[:-2:])
# i=None, j=-2 ==>i=0,索引替换:j=len(s)+j=7
# 1234567
# 负步长
print("*" * 23)
print(str_give[::-1])
# 987654321
print(str_give[6:1:-1])
# i=6, j=1, k=-1 ==> 0<= n <5 ==>[6,5,4,3,2]
# 76543
print(str_give[-3:-8:-1])
# len(s) = 9 同str_give[6:1:-1]
# 76543
print(str_give[6::-1])
# 7654321
print(str_give[-3::-1])
# len(s) = 9 同str_give[6::-1]
# 7654321
print(str_give[:1:-1])
# 9876543
print(str_give[:-8:-1])
# len(s) = 9 同str_give[:1:-1]
# 9876543
print(str_give[8::-1])
# 987654321
print(str_give[-1::-1])
# len(s) = 9 同str_give[8::-1]
# 987654321
str_give = '123456789'
s1 = [str_give[i] for i in range(8, 5, -1)]
print(s1)
#['9', '8', '7']
print(str_give[-3:])
# 789
print(str_give[:5:-1])
987
备注://TODO
在步长为负数时,i或j有一个省略或两个都省略的情况下,尝试去套用公式,但无法确定i和j的默认取值规则,所以这两种情况下暂时公式还是无法匹配,需要进一步尝试公式套用方式。
列表与字典推导式、元组推导式
# 列表推导式
# 从1 到 10 所有偶数的平方
alist = []
for i in range(1,11):
if (i % 2 == 0):
alist.append( i*i )
print(alist)
blist = [i*i for i in range(1, 11) if(i % 2) == 0]
print(type(blist))
print(blist)
执行结果:
[4, 16, 36, 64, 100]
<class 'list'>
[4, 16, 36, 64, 100]
# 字典推导式
# 100以内被3整除的数的平方
adict = {}
for i in range(1,100):
if (i % 3 == 0):
adict[i] = i * i
print(adict)
bdict = {i:i*i for i in range(1, 100) if (i % 3) == 0}
print(type(bdict))
print(bdict)
执行结果:
{3: 9, 6: 36, 9: 81, 12: 144, 15: 225, 18: 324, 21: 441, 24: 576, 27: 729, 30: 900, 33: 1089, 36: 1296, 39: 1521, 42: 1764, 45: 2025, 48: 2304, 51: 2601, 54: 2916, 57: 3249, 60: 3600, 63: 3969, 66:
4356, 69: 4761, 72: 5184, 75: 5625, 78: 6084, 81: 6561, 84: 7056, 87: 7569, 90: 8100, 93: 8649, 96: 9216, 99: 9801}
<class 'dict'>
{3: 9, 6: 36, 9: 81, 12: 144, 15: 225, 18: 324, 21: 441, 24: 576, 27: 729, 30: 900, 33: 1089, 36: 1296, 39: 1521, 42: 1764, 45: 2025, 48: 2304, 51: 2601, 54: 2916, 57: 3249, 60: 3600, 63: 3969, 66:
4356, 69: 4761, 72: 5184, 75: 5625, 78: 6084, 81: 6561, 84: 7056, 87: 7569, 90: 8100, 93: 8649, 96: 9216, 99: 9801}
# 元组推导式
# 元组只能被初始化不能被动态赋值
# atuple = ()
# for i in range(1,11):
# if (i % 2 == 0):
# atuple.append( i*i )
# print(atuple)
# 返回的是一个生成器
btuple = (i*i for i in range(1, 11) if(i % 2) == 0)
print(type(btuple))
print(tuple(btuple))
执行结果:
<class 'generator'>
(4, 16, 36, 64, 100)
关于解包操作
在Python中有一种非常简便的实现方法:
序列解包
假设有字符串:aString = ‘abcd’,
将字符串同时赋予四个变量,既:x1, x2, x3, x4 = aString
那么 x1 就是字符串的第一个元素,x3 就是第三个元素,对序列类型都可以生效的
还有一种情况要在编程中考虑到,如果字符串中的元素比较多的时候,如:aString = ‘abcdefg’
不需要定义更多的变量来一一对应元素个数,可以使用 *(星号)来匹配,同样取出第一个和第三个元素,使用
x1, x2, x3, *x4 = aString # 注意x4变量前面的星号
使用x1, x3 变量依然可以取出第一个和第三个元素
解包操作同样支持集合与字典
需要特别说明的是字典解包出来的Key
a_string = 'abcd'
x1, x2, x3, x4 = a_string
print(x1)
print(x2)
print(x3)
print(x4)
执行结果:
a
b
c
d
a_string = 'abcdefg'
x1, x2, x3, x4, *x5 = a_string
print(x1)
print(x2)
print(x3)
print(x4)
print(*x5)
# print('*x5 type:{}'.format(type(*x5)))
# # Traceback (most recent call last):
# # File "02group.py", line 1245, in <module>
# # print('*x5 type:{}'.format(type(*x5)))
# # TypeError: type.__new__() argument 2 must be tuple, not str
print(x5)
print('x5 type:{}'.format(type(x5)))
执行结果:
a
b
c
d
e f g
['e', 'f', 'g']
x5 type:<class 'list'>
a_list = [1,2,3,4,5]
x1,x2,x3,*x4 = a_list
print(x1)
print(x2)
print(x3)
print(*x4)
print(x4)
执行结果:
1
2
3
4 5
[4, 5]
a_tuple = (1,2,3,23,24)
x1,x2,x3,*x4 = a_tuple
print(x1)
print(x2)
print(x3)
print(*x4)
print(x4)
执行结果:
1
2
3
23 24
[23, 24]
a_set = {1,2,3,12,6}
x1,x2,x3,*x4 = a_set
print(x1)
print(x2)
print(x3)
print(*x4)
print(x4)
执行结果:
1
2
3
6 12
[6, 12]
a_dict = {1:10,2:20,3:30,4:40,5:50}
x1,x2,x3,*x4 = a_dict
print(x1)
print(x2)
print(x3)
print(*x4)
print(x4)
执行结果:
1
2
3
4 5
[4, 5]
参考
互联网相关资料
Python官方文档
Python sequence-types-list-tuple-range