python lxf

在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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值