在python 2.x中
>>> len(u'中文')
2
>>> len('中文')
4
>>> len(u'中文'.encode('utf-8'))
6
>>>
>>> u'ABC'.encode('utf-8')
'ABC'
>>> u'中文'.encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'
在utf-8中 一个中文占用三个字节
但是,再次调用add_end()时,结果就不对了:
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了’END’后的list。
原因解释如下:
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
要修改上面的例子,我们可以用None这个不变对象来实现:
def add_end(L=None):
if L is None:
L = []
L.append(‘END’)
return L
现在,无论调用多少次,都不会有问题:
>>> add_end()
['END']
>>> add_end()
['END']
汉诺塔:带步数
//将步数存到 可变的list中
def move(n,a,b,c,m=[1]):
if n==0:
return
move(n-1,a,c,b,m )
print(str(m[0])+"=="+a+'==>'+c)
m[0]+=1
move(n-1,b,a,c,m )
( )不可变的list 可重复 有序
[] 可变的list 可重复 有序
{} 可变的set 不可重复 无序
dect {‘Michael’: 95, ‘Bob’: 75, ‘Tracy’: 85} 相当于 java的map 无序 不可重复
遍历:
>>> for a,b in enumerate((1,223,21)):
... print(a,b)
...
(0, 1)
(1, 223)
(2, 21)
>>>
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
>>> for p in(1,2,5,6):
... print p
...
1
2
5
6
>>> for p in{3,2,5}:
... print p
...
2
3
5
>>> for p in{3,2,5,3,2,445,2,1}:
... print p
...
1
2
3
445
5
>>> for a,b in[(1,2),(6,2)]:
... print(a,b)
...
(1, 2)
(6, 2)
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> for k, v in d.items():
... print(k, '=', v)
...
y = B
x = A
z = C
列表生成式:
>>> [x for x in range(1,10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [x+1 for x in range(1,10)]
[2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> [x*x for x in range(1,10)]
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
还可以使用两层循环,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
>>> [x*x for x in range(1 , 11) if x%2 == 0]
[4, 16, 36, 64, 100]
>>>
生成器:
>>> def fib1(max):
... n, a, b,c = 0, 0, 1,0
... while n < max:
... yield b
... c=a+b
... a=b
... b=c
... n = n + 1
... #return "done" # 用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
---结果:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
>>> ff=fib1(6)
>>> [x for x in ff]
[1, 1, 2, 3, 5, 8]
>>> ff.next()
想拿到返回值时:
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
举个简单的例子,定义一个generator,依次返回数字1,3,5:
def odd():
print(‘step 1’)
yield 1
print(‘step 2’)
yield(3)
print(‘step 3’)
yield(5)
调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
杨辉三角:
>>> def triangles(max):
... n=1
... m=[1]
... t=[]
... while n<max+1:
... if(n==1):
... m=[1]
... elif(n==2):
... m=[1,1]
... else:
... t=m[:]
... for i,x in enumerate(m):
... if(i>0):
... t[i]=m[i-1]+m[i]
... t.append(1)
... m=t
... yield t
... n+=1
...
>>> ff=triangles(5)
>>> ff.next()
[1]
>>> ff.next()
[1, 1]
>>> ff.next()
[1, 2, 1]
>>> ff.next()
[1, 3, 3, 1]
>>> ff.next()
[1, 4, 6, 4, 1]
>>> ff.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> ff=triangles(5)
>>> [x for x in ff]
[[1, 1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1]]
>>> n = 0
>>> for t in triangles(10):
... print(t)
... n = n + 1
... if n == 10:
... break
...
[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]
>>>
精简 代码:
先用append 在最后面append一个0
巧用N[-1] =0
N = [1]
while True:
yield N
N.append(0)
N = [N[i-1] + N[i] for i in range(len(N))]
最开始是 N【1】
然后 N.append(0) 就变成了 【1,0】
那个循环长度为2
那么第一次 新N【0】=N【-1】+N【0】=1(N【-1】就是倒数最后一个元素)
第二次 新N【1】=N【0】+ N【1】=1
所以此时的N 就是 【1,1】
以此类推 第二排 N=【1,1,0】(循环次数等于长度)
第一次循环 新N【0】=N【-1】+N【0】=1
新N【1】=N【0】+N【1】=2
新 N【2】=N【1】+N【2】=1
嗯,大概就是这意思
还有个不错的:
def triangles():
temp = [1]
while True:
yield temp
temp = [1, *[temp[i] + temp[i + 1] for i in range(len(temp) - 1)], 1]
triangle = triangles();
for i in range(10):
print(next(triangle))