我不觉得跌倒可怕,可怕的是再也站不起来! ——任正非
1.线性结构可以索引
lst,tuple,str,bytes,bytearay:
tuple:占用内存小;
可迭代for...in
len()可以获取长度; # length(python 专有的设计思想 )
可以索引,切片;
2. 切片[] ->【) #前包后不包
2.1 切片操作的返回结果是一个新的独立的序列。以列表为例,列表切片后得到的还是一个列表,占用新的内存地址。
切片只是浅拷贝,它拷贝的是原列表中元素的引用,所以,当存在变长对象的元素时,新列表将受制于原列表。
'www.magedu.com'[4:10] | 'magedu'
#取不出值,不会报错,只是没有结果;
bytearray(b'www.magedu.com')[-4:10] | bytearray(b'')
tuple('www.magedu.com')[-10:10] | ('m', 'a', 'g', 'e', 'd', 'u')
list('www.magedu.com')[-10:10:1] | ['m', 'a', 'g', 'e', 'd', 'u']
list('www.magedu.com')[-10:10:-1] | []
str与list、tuple输出的结果不同,str输出一段字符;tuple\list依次输出单个字符;
# 切片的使用中还可以再添加一个可选择的索引参数:
s = 'abcdefghijk'
# 偏移从0开始,直到不含偏移量为11,每隔2个元素索引一次构成最终的新字符串
print(s[:11:2]) | acegik
# 偏移从11开始,直到不含偏移量为0,每隔2个元素索引一次构成最终的新字符串
print(s[11::-2]) | kigeca
# 即从右向左,每隔一个元素索引一次,效果即翻转字符串
print(s[::-1])
总结:
for c in 'www.magedu.com'[::-1] 与 reversed(lst) 比较,for 迭代既浪费空间又浪费时间;reversed只是浪费时间;
3.习题练习;
clipboard.png杨辉三角新特性
组合数公式:C(n,m)=n!/((n-m)!*m!)(m≤n)
3.1 # 打印杨辉三角第m行第 k 个元素;
# 求杨辉三角的第m行第k个元素;
# 方法1:大框架下 小列表打印;索引列表的值;
lst=[]
m=5
k=4
for i in range(m): #大框架下 小列表打印;索引列表的值;
row=[1]
lst.append(row)
if i==0:
continue
for j in range(1,i):
row.append(lst[i-1][j-1]+lst[i-1][j])
row.append(1)
print(lst)
print("------")
print(lst[m-1][k-1]) #109us
-----------------------------------------------------
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
------
4
方法2:计算所有元素后,list索引
n=6
row=[1]*n #一次性开辟足够的空间;
lst=[]
for i in range(n):
offset=n-i
z=1 #因为会有覆盖影响计算,索引引入一个临时变量;
for j in range(1,i//2+1):
val=z+row[j]
row[j],z=val,row[j]
if i !=2*j:
row[-j-offset]=val
lst.append(row[:i+1])
print(lst)
# 输出第m行k个元素;k<=m;
m=int(input('>>>')) #行;
k=int(input('>>>')) #第几个值;
print('第{}行第{}个值为{}'.format(m,k,lst[m][k-1]))
---------------------------------------------
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]]
>>>5
>>>4
第5行第4个值为10
方法3: 根据杨辉三角新特性组合数计算m行k个值;
# 学习公式的写法,技巧,怎么样效率最高; 把公式转化为算法实现;
思考:为什么写三个if?而不是if...elif(***)
# 组合数算阶乘的方法;
n=5
r=3
d=2
lst=[]
f=1
for i in range(1,n+1): #算阶乘的方法;
f*=i
if i==r:
lst.append(f)
if i==d:
lst.append(f)
if i==n:
lst.append(f)
print(lst,type(lst[2]))
print(lst[2]//(lst[0]*lst[1]))
-------------------------
[2, 6, 120] <class 'int'>
10
3.2 # 给定一个3*3的方阵,求其转置矩阵;
# 方法1:打印的解题思路;
m='1 2 3\n4 5 6\n7 8 9'
#print(m)
l_c=len(m.split('\n')) #3
m=m.split() #->list[]
l_row=len(m)//l_c # 3
for i in range(l_row):
for j in range(l_c):
print(m[j*3+i],end=' ')
print('\r')
---------------------------------------------------------------
1 4 7
2 5 8
3 6 9
# 方法2 方阵转换的思路;
m=[[1,2,3],[4,5,6],[7,8,9]] #写成二维数组;
for i in range(3):
for j in range(i):
m[i][j],m[j][i]=m[j][i],m[i][j] # 3 维方阵交换3次; 数值为 0 、1、2;
print(m)
-----------------------------
1 4 7
2 5 8
3 6 9
总结:
# for 循坏的几种写法含义理解不深:
for i in lst:
for j in lst:
for i in lst;
for j in i:
# 优化方案:
# 1.对角线的取值,是否交换;
# 2.写成data写成 二维数组,否则会绕大湾子;
# 3.数组不建议进行二次索引,二次索引是建立在list中都是单个字符的情况;
方法3 矩阵的打印;不打印对角线
lst1=[[1,2,3],[4,5,6],[7,8,9]]
for x in range(len(lst1)):
for y in range(len(lst1[x])):
if y>x: # 除去对角线的打印;
lst1[x][y],lst1[y][x]=lst1[y][x],lst1[x][y]
lst1
-----------------------------
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
方法3 enumerate() 函数的使用
enumerate(sequence, [start=0])
enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>>list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>>list(enumerate(seasons, start=1)) # 小标从 1 开始
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
3.3 # 给定一个不规则矩阵(23)的方阵,求其转置矩阵(有点难为人)*
# 方法1 enumerate()函数写法;
lst=[[1,2,3],[4,5,6]]
for i,y in enumerate(lst[1],1):
print(i,y)
-------------------------
1 4
2 5
3 6
方法2:一此行开辟所有空间+列表解析式;
m=[[1,4],[2,5],[3,6]]
tm=[[0 for col in range(len(m))] for row in range(len(m[0]))] #开辟空间 ;列表解析式 效率更高;
count=0
for i,row in enumerate(tm):
for j,col in enumerate(row):
tm[i][j]=m[j][i] #将m所有的元素搬到tm中;一次都少不了
count+=1
print(m)
print(tm)
print(count)
----------------------------------------
[[1, 4], [2, 5], [3, 6]]
[[1, 2, 3], [4, 5, 6]]
6
总结:
1.tm=[[0 for col in range(len(m))] for row in range(len(m[0]))] #开辟空间 ;列表解析式;
2. tm[i][j]=m[j][i] #将m所有的元素搬到tm中;一次都少不了
3.append方法与for循坏迭代快慢比较:可能的原因:数据的规模大小,而不是append比for快;
方法3: append方法
m=[[1,2,3],[4,5,6]]
tm=[]
count=0
for row in m:
for i,col in enumerate(row):
if len(tm)<i+1: # m有i列就要为tm创建i行;
tm.append([])
tm[i].append(col)
count+=1
print(m)
print(tm)
print(count)
------------------------------------------
[[1, 2, 3], [4, 5, 6]]
[[1, 4], [2, 5], [3, 6]]
6
数字统计
3.4 # 随机产生10个数字【10,20】,统计重复的数字有几个;不重复的数字有几个,分别是什么?
#4.随机生成10个数字;统计重复和不重复数字的个数和值;
方法1:list count 实现方法
lst=[]
for i in range(10):
lst.append(random.randint(1,20))
lst1=[]
m=0
for i in range(10):
#print(lst[i],lst.count(lst[i]))
n=lst.count(lst[i])
if n>1 and lst[i] not in lst1:
lst1.append(lst[i])
m+=1
print('重复的数字有{}个,分别为{}'.format(m,lst1))
---------------------------------------------------------------
重复的数字有3个,分别为[14, 2, 13]
解法2:
import random
nums=[]
for _ in range(10): # for循坏的i值可以为任意;包括符号
nums.append(random.randint(1,20))
print("Origin numbers = {}".format(nums))
print('-----------------------------------')
length=len(nums)
samenums=[] #记录相同的数字;
diffnums=[] #记录不同的数字;
states=[0]*length #记录不同的索引状态;
for i in range(length):
flag=False #假定没有重复;
if states[i]==1:
continue
for j in range(i+1,length):
if states[j]==i:
continue
if nums[i]==nums[j]:
flag=True
states[j]=1
if flag: #有重复;
samenums.append(nums[i])
states[i]=1
else:
diffnums.append(nums[i])
print("Same numbers={1},Counter={0}".format(len(samenums),samenums))
print("Different numbers={1},Counter={0}".format(len(diffnums),diffnums))
print(list(zip(states,nums)))
-----------------------------------------------------------------------------------
Origin numbers = [1, 7, 5, 14, 10, 19, 8, 9, 10, 11]
-----------------------------------
Same numbers=[10],Counter=1
Different numbers=[1, 7, 5, 14, 19, 8, 9, 11],Counter=8
[(0, 1), (0, 7), (0, 5), (0, 14), (1, 10), (0, 19), (0, 8), (0, 9), (1, 10), (0, 11)]
总结:
1. for循坏的i值可以为任意;包括符号;
网友评论