Python学习记录
从这学期(2018.3)开始了学习python,由于以前太怠惰底子不好,学习比较慢,于是决定记录下来这个过程-0-
刚入门是跟着廖雪峰的python教程写的!个人觉得很不错!
python的高级特性-切片:
我们会经常取一个list或tuple中的部分元素出来,如果每次取少量元素,可以直接使用索引取出,若是取出n(n非常大)个元素时,明显这样做是不理智的。因此,Python提供了切片操作符。
L[a:b]则表示取出L中从L[a]开始到L[b-1]的所有元素,例:
L=['doris','spensor','aria','alison"]
L[0:3]=L[:3]=L[0:]=['doris','spensor','aria']
L[1:3]=['spensor','aria']
也可以使用复数,表示倒序切片
L[-2:]=['aria','alison"]
练习
利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法:
def trim(s):
while(s[:1]==' '):
s=s[1:]
while(s[-1:]==' '):
s=s[:-1]
if(s):
return s
else:
return ''
列表生成式:
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]可以用list(range(1, 11))
一些例子:
①
s=[x*x for x in range(1,11) if x*2==0]
print(s)----->[4,16,36,64,100]
②
还可以使用两层循环,可以生成全排列:
>>>[m+n for m in 'ABC' for n in 'XYZ']
['AX','AY','AZ','BX','BY','BZ','CX','CY','CZ']
③
同时使用多个变量:
>>>d={'x':'A','y':'B','z':'C'} #d是一个dict
>>>for k,v in d.items():
print(k,'=',v)
y=B
x=A
z=C #dict内部存放的顺序和key放入的顺序是没有关系的
生成器(重点):
如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
创建generator:
>>>g=(x*x for x in range(10))
>>>g
<generator object<genexpr> at 0x1022ef630>
如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值。
generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
定义generator的另一种方法:
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:
函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
例:
def odd():
print("step1')
yield 1
print("step2')
yield 3
print("step3')
yield 5
>>>0=0dd()
>>>next(o)
step1
1
>>>next(o)
step2
3
>>>next(o)
step3
5
>>>next(o)
Traceback (more recent call last):
File"<stdin>",line 1,in <module>
StopIteration #执行3次yield后,已经没有yield可以执行了,所以,第4次调用next(o)就报错。
练习:
杨辉三角定义如下:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
# 期待输出: # [1] # [1, 1] # [1, 2, 1] # [1, 3, 3, 1] # [1, 4, 6, 4, 1] # [1, 5, 10, 10, 5, 1] # [1, 6, 15, 20, 15, 6, 1] # [1, 7, 21, 35, 35, 21, 7, 1] # [1, 8, 28, 56, 70, 56, 28, 8, 1] # [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
测试程序n = 0results = []
for t in triangles():
print(t)
results.append(t)
n = n + 1
if n == 10:
break
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
编写generator:
def triangles():
L = [1]
while True:
yield L
L.append(0)
L = [L[i - 1] + L[i] for i in range(len(L))]
解析:
杨辉三角每一行的每个元素是由前一行的相邻元素相加得到,而每行的首位又保持为1,
核心思路在于L.append(0)这一行代码,也就是每次都在list末尾添加一个0,
用于让每行的首尾等于1并让列表生成式的计数器+1(len())
这样,L = [L[i - 1] + L[i] for i in range(len(L))]
得到的第一个元素是原数组的倒数第一个元素(即0)加上第一个元素(1)等于1,#L[-1]表示倒数第一个元素
最后一个元素是原数组的倒数第二个元素(即1)加上倒数第一个元素(0)等于1,满足了条件。
这里补零和-1取倒数的思想非常重要!
但是!!!
我们会发现,测试不通过,因为每一行(除了最后一行)后面都多了一个0
你或许会疑问,0不是在yield之后再加上去的吗,为什么会显示出来呢?
这里就需要提到python中的赋值,其实都是对象的引用,L总是指向那片内存,
L.append(0) 执行后,L指向的地址的内容发生了变化
这里如果我们使用拷贝,则可测试通过
def triangles():
L = [1]
while True:
yield L
temp = L.copy()
temp.append(0)
L = [temp[i-1]+temp[i] for i in range(len(temp))]
注意理解!
(-------------------------18.3.30---------------------------)
浙公网安备 33010602011771号