python3.6.4的學習

[root@mantisbt01 python]# ./13.py
Please input your name:hadoop
Please input your height(m):1.80
Please input your height(kg):75.3
hadoop , Your bmi value is: 23.24 !
Your body type is 正常
[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.

>> abs(12)
12
>> abs(-12)
12
>> abs(0)
0
>> abs(-12.3)
12.3
>> abs(12.3)
12.3
>> abs(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)
>> abs(f)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'f' is not defined
>> max(1,2)
2
>> max(1,2,23,4)
23
>> max(1,2,23,4,-9,0)
23
>> int(321)
321
>> int(12.32)
12
>> float(12.32)
12.32
>> float(12)
12.0
>> float('12.32')
12.32
>> str(100)
'100'
>> str(13)
'13'
>> str(as)
File "<stdin>", line 1
str(as)
^
SyntaxError: invalid syntax
>> str('as')
'as'
>> str('a')
'a'
>> str(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>> bool(1)
True
>> bool(-1)
True
>> bool(0)
False
>> bool(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>> bool('a')
True
>> a=abs
>> a(-2)
2
>> n1=255
>> n2=1000
>> hex(n1)
'0xff'
>> hex(n2)
'0x3e8'

>> def my_abs(x):
... if x >=0:
... return x
... else:
... return -x
...
>> my_abs(-9)
9
>> my_abs(-8)
8
>> my_abs(8)
8
>> my_abs(0)
0
>> my_abs(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in my_abs
TypeError: '>=' not supported between instances of 'builtin_function_or_method' and 'int'
>> my_abs('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in my_abs
TypeError: '>=' not supported between instances of 'str' and 'int'
>>

[root@mantisbt01 python]# pwd
/root/python
[root@mantisbt01 python]# cat 14.py
def my_abs(x):
if x >=0:
return x
else:
return -x
[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.

>> from 14 import my_abs
File "<stdin>", line 1
from 14 import my_abs
^
SyntaxError: invalid syntax
>>
KeyboardInterrupt
>>
[root@mantisbt01 python]# mv 14.py abstest.py
[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>> from abstest import my_abs
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/python/abstest.py", line 3
return x
^
TabError: inconsistent use of tabs and spaces in indentation
>>
[root@mantisbt01 python]# vi abstest.py
[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>> from abstest import my_abs
>> my_abs(-18)
18
>> my_abs(19)
19
>> my_abs(0)
0
>> my_abs('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/python/abstest.py", line 2, in my_abs
if x >=0:
TypeError: '>=' not supported between instances of 'str' and 'int'
>> my_abs(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>
>> def nop():
... pass
...
>>
>> if age >=18:
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'age' is not defined
>> age=10
>> if age >=18:
... age
...
>>
>> my_abs(2)
2
>> my_abs(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: my_abs() takes 1 positional argument but 2 were given
>> my_abs('A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/python/abstest.py", line 2, in my_abs
if x >=0:
TypeError: '>=' not supported between instances of 'str' and 'int'
>> abs('A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'
>>
[root@mantisbt01 python]# cp -p abstest.py abstest2.py
[root@mantisbt01 python]#
[root@mantisbt01 python]# vi abstest2.py
[root@mantisbt01 python]# cat abstest2.py
def my_abs(x):
if not isinstance(x,(int,float)):
raise TypeError('bad operand type')
if x >=0:
return x
else:
return -x
[root@mantisbt01 python]#

[root@mantisbt01 python]# cp -p abstest.py abstest2.py
[root@mantisbt01 python]#
[root@mantisbt01 python]# vi abstest2.py
[root@mantisbt01 python]# cat abstest2.py
def my_abs(x):
if not isinstance(x,(int,float)):
raise TypeError('bad operand type')
if x >=0:
return x
else:
return -x
[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.

>> from abstest2 import my_abs
>> my_abs(-9)
9
>> my_abs(9)
9
>> my_abs(0)
0
>> my_abs('A')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/root/python/abstest2.py", line 3, in my_abs
raise TypeError('bad operand type')
TypeError: bad operand type
>>

>> import math
>> def move(x,y,step,angle=0):
... nx = x + step math.cos(angle)
... ny = y + step
math.sin(angle)
... return nx,ny
...
>> x,y=move(100,100,60,math.pi / 6)
>> print(x,y)
151.96152422706632 130.0
>> r = move(100,100,60,math.pi / 6)
>> print(r)
(151.96152422706632, 130.0)
>>

>> r
(151.96152422706632, 130.0)
>>

[root@mantisbt01 python]# cat 14.py
#!/usr/bin/python

#-- coding: utf-8 --

import math
def quadratic(a,b,c):
if not ( isinstance(a,(int,float)) and isinstance(b,(int,float)) and isinstance(c,(int,float)) ):
raise TypeError('bad operand type')
delta=(b*2)-(4bc)
if delta < 0:
print('delta小於零,方程無解')
else:
x1=(-b+math.sqrt(delta))/(2
a)
x2=(-b-math.sqrt(delta))/(2*a)
print('x1=%.2f x2=%.2f'%(x1,x2))
return x1,x2

print('quadratic(2,3,1)=',quadratic(2,3,1))
print('quadratic(1,3,-4)=',quadratic(1,3,-4))
[root@mantisbt01 python]# ./14.py
delta小於零,方程無解
quadratic(2,3,1)= None
x1=2.27 x2=-5.27
quadratic(1,3,-4)= (2.274917217635375, -5.274917217635375)
[root@mantisbt01 python]#

>> def power(x):
... return x*x
...
>> power(4)
16
>> power(2)
4
>> power(3)
9
>> power(11)
121

>> def power(x,n)
File "<stdin>", line 1
def power(x,n)
^
SyntaxError: invalid syntax
>> def power(x,n):
... s=1
... while n > 0:
... n=n-1
... s=s*x
... return s
...
>> power(2,3)
8
>> power(3,3)
27
>> power(3,4)
81
>>

>> power(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'
>> def power(x,n=2):
... s=1
... while n > 0:
... n=n-1
... s=sx
... return
...
>> power(5)
>> def power(x,n=2):
... s=1
... while n > 0:
... n=n-1
... s=s
x
... return s
...
>> power(5)
25
>> power(3)
9
>> power(3,4)
81
>>

>> def enroll(name,gender):
... print('name:',name)
... print('gender:',gender)
...
>> enroll('Sarah','F')
name: Sarah
gender: F
>> def enroll(name,gender,age=6,city='Beijing'):
... print('name:',name)
... print('gender',gender)
... print('age:',age)
... print('city:',city)
...
>>
>> enroll('Sarah','F')
name: Sarah
gender F
age: 6
city: Beijing
>> enroll('Bob','M',8)
name: Bob
gender M
age: 8
city: Beijing
>> enroll('Adam','M',city='shanghai')
name: Adam
gender M
age: 6
city: shanghai

>> def add_end(L=[]):
... L.append('END')
... return L
...
>> add_end([1,2,3])
[1, 2, 3, 'END']
>> add_end(['x','y','z'])
['x', 'y', 'z', 'END']
>> add_end([1,2,3])
[1, 2, 3, 'END']
>> add_end()
['END']
>> add_end()
['END', 'END']
>> add_end()
['END', 'END', 'END']
>> add_end()
['END', 'END', 'END', 'END']
>> def add_end(L=[]):
... if L is None:
... L=[]
... L.append('END')
... return L
...
>> add_end()
['END']
>> add_end()
['END', 'END']
>> add_end()
['END', 'END', 'END']
>> def add_end(L=None):
... if L is None:
... L=[]
... L.append('END')
... return L
...
>> add_end()
['END']
>> add_end()
['END']
>> add_end()
['END']
>>

>>
>> def calc(number):
... sum=0
... for n in number:
... sum=sum+nn
... return sum
...
>> calc([1,2,3])
14
>> calc([1,2,3,4])
30
>> calc(1,2,3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: calc() takes 1 positional argument but 3 were given
>>
>> def calc(
number):
... sum=0
... for n in number:
... sum=sum+n*n
... return sum
...
>> calc(1,2,3)
14
>> calc([1,2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in calc
TypeError: can't multiply sequence by non-int of type 'list'
>> calc(1,2,3,4)
30
>>

>> calc(1,2)
5
>> calc()
0
>> nums = [1,2,3]
>> calc(nums[0],nums[1],nums[2])
14
>> calc(*nums)
14
>>

關鍵字參數

>>
>> def person(name,age,kw):
... print('name:',name,'age:',age,'other:',kw)
...
>>
>> person('Michael',30)
name: Michael age: 30 other: {}
>> person('Bob',35,city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>> person('Adam',45,gender='M',job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
>>
>> extra={'city':'Beijing','job':'Engineer'}
>> person('Jack',24,city=extra['city'],job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
>>
>> person('Jack',24,
extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
>>
extra表示把extra這個dict的所有key-value用關鍵字參數傳入到函數的kw參數,kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函數外的extra.

命名關鍵字參數

>> def person(name,age,**kw):
... if 'city' in kw:
... pass
... if 'job' in kw:
... pass
... print('name',name,'age',age,'other:',kw)
...
>> person('Jack',24,city='Beijing',addr='Chaoyang',zipcode=123456)
name Jack age 24 other: {'city': 'Beijing', 'addr': 'Chaoyang', 'zipcode': 123456}
>>

>> def person(name,age,*,city,job):
... print(name,age,city,job)
...
>> person('Jack',24,city='Beijing',job='Engineer')
Jack 24 Beijing Engineer
>>

如果函數定義中已經有了一個可變參數,後面跟着的命名關鍵字參數就不再需要一個特殊分隔符*了:

>>
>> def person(name,age,args,city,job):
... print(name,age,args,city,job)
...
>> person('Jack',24,'Beijing','Engineer')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'
>> person('Jack',24,city='Beijing','Engineer')
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>> person('Jack',24,city='Beijing',job='Engineer')
Jack 24 () Beijing Engineer
>>
>>
命名關鍵字參數可以有缺省值,從而簡化調用:
>>
>>
>> def person(name,age,
,city='Beijing',job):
... print(name,age,city,job)
...
由於命名關鍵字參數city具有默認值,調用時,可不傳入city參數:
>> person('Jack',24,job='Engineer')
Jack 24 Beijing Engineer
>>

參數組合

>> def f1(a,b,c=0,*args,*kw):
... print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)
...
>>
>> def f2(a,b,c=0,
,d,**kw):
... print('a=',a,'b=',b,'c=',c,'d=',d,'kw=',kw)
...
>>
>> f1(1,2)
a= 1 b= 2 c= 0 args= () kw= {}
>> f1(1,2,c=3)
a= 1 b= 2 c= 3 args= () kw= {}
>> f1(1,2,'a','b')
a= 1 b= 2 c= a args= ('b',) kw= {}
>> f1(1,2,3,'a','b')
a= 1 b= 2 c= 3 args= ('a', 'b') kw= {}
>> f1(1,2,3,'a','b','c')
a= 1 b= 2 c= 3 args= ('a', 'b', 'c') kw= {}
>> f1(1,2,3,'a','b','c',x=98)
a= 1 b= 2 c= 3 args= ('a', 'b', 'c') kw= {'x': 98}
>>
>> f2(1,2,d=23,ext=None)
a= 1 b= 2 c= 0 d= 23 kw= {'ext': None}
>>

通過一個tuple和dict,也可以調用上述函數:

>> args=(1,2,3,4)
>>
>> kw={'d':99,'x':'#'}
>>
>> f1(*args,kw)
a= 1 b= 2 c= 3 args= (4,) kw= {'d': 99, 'x': '#'}
>>
>>
>> f2(*args,*kw)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f2() takes from 2 to 3 positional arguments but 4 positional arguments (and 1 keyword-only argument) were given
>>
>> args=(1,2,3)
>>
>> kw={'d':88,'x':'#'}
>>
>> f2(
args,
kw)
a= 1 b= 2 c= 3 d= 88 kw= {'x': '#'}
>>

[root@mantisbt01 python]# cat ./15.py
#!/usr/bin/python

#-- coding:utf-8 --

def product(numbers):
product=1
if numbers==():
raise TypeError
else:
for n in numbers:
product=product
n

print('product =',product)

    return product

#test
print('product(5) =',product(5))
print('product(5,6) =',product(5,6))
print('product(5,6,7) =',product(5,6,7))
print('product(5,6,7,9) =',product(5,6,7,9))

if product(5) != 5:
print('test failed!')
elif product(5,6) != 30:
print('test failed!')
elif product(5,6,7) != 210:
print('test failed!')
elif product(5,6,7,9) != 1890:
print('test failed!')
else:
try:
product()
print('test failed!')
except TypeError:
print('test successful')
[root@mantisbt01 python]# ./15.py
product(5) = 5
product(5,6) = 30
product(5,6,7) = 210
product(5,6,7,9) = 1890
test successful
[root@mantisbt01 python]#

遞歸函數

>> def fact(n):
... if n==1:
... return 1
... return n*fact(n-1)
...
>> fact(1)
1
>> fact(5)
120
>> fact(100)
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
>> fact(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in fact
File "<stdin>", line 4, in fact
File "<stdin>", line 4, in fact
[Previous line repeated 994 more times]
File "<stdin>", line 2, in fact
RecursionError: maximum recursion depth exceeded in comparison
>>

[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.

>> def fact(n):
... return fact_iter(n,1)
...
>> def fact_iter(num,product):
... if num==1:
... return product
... return fact_iter(num-1,num*product)
...
>> fact_iter(5,1)
120
>> fact_iter(10,1)
3628800
>> fact_iter(1,1)
1
>> fact_iter(20,1)
2432902008176640000
>> fact_iter(1000,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in fact_iter
File "<stdin>", line 4, in fact_iter
File "<stdin>", line 4, in fact_iter
[Previous line repeated 994 more times]
File "<stdin>", line 2, in fact_iter
RecursionError: maximum recursion depth exceeded in comparison
>>

>> fact(10)
3628800
>> def fact(n):
... s=1
... for i in range(1,n+1):
... s=si
... return s
...
>> fact(10)
3628800
>> fact(5)
120
>> from functools import reduce
>> def Fact(n):
... return reduce((lambda x,y:x
y),list(range(1,n+1)))
...
>> Fact(5)
120
>> Fact(10)
3628800
>>

漢諾塔的移動可以用遞歸函數非常簡單地實現。

請編寫move(n, a, b, c)函數,它接收參數n,表示3個柱子A、B、C中第1個柱子A的盤子數量,然後打印出把所有盤子從A藉助B移動到C的方法,例如:
[root@mantisbt01 python]# cat ./17.py
#!/usr/bin/python

#-- coding:utf-8 --

def move(n,a,b,c):
if n==1:
step=1
print(a,'-->',c)
return step
else:
s1=move(n-1,a,c,b)
s2=move(1,a,b,c)
s3=move(n-1,b,a,c)
step=s1+s2+s3
return step

s=move(3,'A','B','C')
print('need %d steps'%s)
[root@mantisbt01 python]# ./17.py
A --> C
A --> B
C --> B
A --> C
B --> A
B --> C
A --> C
need 7 steps
[root@mantisbt01 python]#

高級特性
比如構造一個1, 3, 5, 7, ..., 99的列表,可以通過循環實現:

L = []
n = 1
while n <= 99:
L.append(n)
n = n + 2
取list的前一半的元素,也可以通過循環實現。

但是在Python中,代碼不是越多越好,而是越少越好。代碼不是越複雜越好,而是越簡單越好。

基於這一思想,我們來介紹Python中非常有用的高級特性,1行代碼能實現的功能,決不寫5行代碼。請始終牢記,代碼越少,開發效率越高。
法1:

>> L=[]
>> n=1
>> while n<=99:
... L.append(n)
... n=n+2
...
>> L
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
>>

法2:

>> print(list(range(1,100,2)))
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]

法3:

>> print([i for i in range(1,100,2)])
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
>>

1.切片
1.1 list

>> L=['Michael','Sarah','Tracy','Bob','Jack']
>> [L[0],L[1],L[2]]
['Michael', 'Sarah', 'Tracy']
>> [L[-1],L[-2],L[-3]]
['Jack', 'Bob', 'Tracy']
>> r=[]
>> n=3
>> for i in range(n):
... r.append(L[i])
...
>> r
['Michael', 'Sarah', 'Tracy']
>> L[0:3]
['Michael', 'Sarah', 'Tracy']
>> L[0:4]
['Michael', 'Sarah', 'Tracy', 'Bob']
>> L[1:3]
['Sarah', 'Tracy']
>> L[:3]
['Michael', 'Sarah', 'Tracy']
>> L[-2:]
['Bob', 'Jack']
>> L[-2:-1]
['Bob']
>> L[-1]
'Jack'
>> L=list(range(100))
>> L
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>> L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>> L[2:10:2]
[2, 4, 6, 8]
>> L[2:10:3]
[2, 5, 8]
>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
>> L[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>

1.2 tuple

>> (0,1,2,3,4,5)[:3]
(0, 1, 2)
>> 'ABCDEFG'[:3]
'ABC'
>> 'ABCDEFG'[::2]
'ACEG'
>>

利用切片操作,實現一個trim()函數,去除字符串首尾的空格,注意不要調用str的strip()方法:
[root@mantisbt01 python]# cat 18.py
#!/usr/bin/python

#-- coding:utf-8 --

#def trim(s):

if len(s) == 0:

return s

elif s[0] == '':

return (trim(s[1:]))

elif s[-1] == ' ':

return (trim(s[:-1]))

return s

def trim(s):
if s[:1] != ' ' and s[-1:] != ' ':
return s
elif s[:1] == ' ':
return trim(s[1:])
else:
return trim(s[:-1])

if trim('hello ') != 'hello':
print('測試失敗!')
elif trim(' hello') != 'hello':
print('測試失敗!')
elif trim(' hello ') != 'hello':
print('測試失敗!')
elif trim(' hello world ') != 'hello world':
print('測試失敗!')
elif trim('') != '':
print('測試失敗!')
elif trim(' ') != '':
print('測試失敗!')
else:
print('測試成功!')
[root@mantisbt01 python]# ./18.py
測試成功!

2.迭代

>> d={'a':1,'b':2,'c':3}
>> for key in d:
... print(key)
...
a
b
c
>> for ch in 'ABC':
... print(ch)
...
A
B
C
>>
>> from collections import Iterable
>> isinstance('abc',Iterable)
True
>> isinstance([1,2,3],Iterable)
True
>> isinstance(123,Iterable)
False
>>
>> for i,value in enumerate(['A','B','C']):
... print(i,value)
...
0 A
1 B
2 C
>> for x,y in [(1,1),(2,4),(3,9)]:
... print(x,y)
...
1 1
2 4
3 9
>>

請使用迭代查找一個list中最小和最大值,並返回一個tuple:
使用冒泡排序法
[root@mantisbt01 python]# cat 19.py
#!/usr/bin/python

#-- coding:utf-8 --

def findMinandMax(L):
if (L==[]):
return (None,None)
else:
num=len(L)
for i in range(num):
for j in range(i):
if L[i]<L[j]:
L[i],L[j]=L[j],L[i]
return (L[0],L[-1])

if findMinandMax([]) != (None,None):
print('測試失敗!')
elif findMinandMax([7]) != (7,7):
print('測試失敗!')
elif findMinandMax([7,1]) != (1,7):
print('測試失敗!')
elif findMinandMax([7,1,3,9,5]) != (1,9):
print('測試失敗!')
else:
print('測試成功')
[root@mantisbt01 python]#
[root@mantisbt01 python]# ./19.py
測試成功

3.列表生成式

>>
>> list(range(1,11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>> L=[]
>> for x in range(1,11):
... L.append(xx)
...
>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>> [x
x for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

>> [x*x for x in range(1,11) if x%2 == 0]
[4, 16, 36, 64, 100]

>> [m+n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

>> import os
>> [d for d in os.listdir('.')]
['18.py', '19.py', '1.py', '2.py', '3.py', '4.py', '5.py', '6.py', '7.py', '8.py', '9.py', '10.py', '11.py', '12.py', '13.py', 'abstest.py', 'pycache', 'abstest2.py', '14.py', '15.py', '16.py', '17.py']

>> [d for d in os.listdir('/')]
['boot', 'dev', 'proc', 'run', 'sys', 'etc', 'root', 'var', 'tmp', 'usr', 'bin', 'sbin', 'lib', 'lib64', 'home', 'media', 'mnt', 'opt', 'srv', '.autorelabel']

>> [d for d in os.listdir('/home')]
['test2', 'test3', 'test4', 'test1']

>> d={'x':'A','y':'B','z':'C'}
>> for k,v in d.items():
... print(k,'=',v)
...
x = A
y = B
z = C
>>
>> d={'x':'A','y':'B','z':'C'}
>> [k+'='+v for k,v in d.items()]
['x=A', 'y=B', 'z=C']
>> L=['Hello','World','IBM','Apple']
>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']
>>
>>

>> L=['Hello','World',18,'IBM','Apple']
>> [s.lower() for s in L]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in <listcomp>
AttributeError: 'int' object has no attribute 'lower'
>>

[root@mantisbt01 python]# cat 20.py
#!/usr/bin/python

#-- coding:utf-8 --

L1=['Hello','World',18,'IBM',None]
L2=[s.lower() for s in L1 if isinstance(s,str)]

print(L2)
if L2 == ['hello','world','ibm']:
print('測試通過!')
else:
print('測試失敗')
[root@mantisbt01 python]# ./20.py
['hello', 'world', 'ibm']
測試通過!
[root@mantisbt01 python]#

4.生成器

>> L=[xx for x in range(10)]
>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>
>> g=(x
x for x in range(10))
>> g
<generator object <genexpr> at 0x7f8ab91c8570>
>> next(g)
0
>> next(g)
1
>> next(g)
4
>> next(g)
9
>> next(g)
16
>> next(g)
25
>> next(g)
36
>> next(g)
49
>> next(g)
64
>> next(g)
81
>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>
>> g=(x*x for x in range(10))
>> for n in g:
... print(n)
...
0
1
4
9
16
25
36
49
64
81
>> def fib(max):
... n,a,b=0,0,1
... while n < max:
... print(b)
... a,b=b,a+b
... n=n+1
... return 'done'
...
>> fib(6)
1
1
2
3
5
8
'done'
>>
>> def fib(max):
... n,a,b=0,0,1
... while n < max:
... yield b
... a,b=b,a+b
... n=n+1
... return 'done'
...
>> f=fib(6)
>> f
<generator object fib at 0x7f8ab91c8620>
>>
>> def odd():
... print('step 1')
... yield 1
... print('step 2')
... yield(3)
... print('step 3')
... yield(5)
...
>> 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
>> for n in fib(6):
... print(n)
...
1
1
2
3
5
8
>> 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
>>

練習

[root@mantisbt01 python]# cat ./21.py
#!/usr/bin/python

#-- coding:utf-8 --

def triangles():
L=[1]
while True:
yield L
L = [x+y for x,y in zip([0]+L,L+[0])]

n = 0
results = []
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('測試失敗!')
[root@mantisbt01 python]# ./21.py
[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]
測試通過!
[root@mantisbt01 python]# cat ./22.py
#!/usr/bin/python

#-- coding:utf-8 --

def triangles():
L=[1]
while True:
yield L
L = [x+y for x,y in zip([0]+L,L+[0])]

n = 0
results = []
for t in triangles():
print(t)
results.append(t)
n = n + 1
if n == 15:
break
[root@mantisbt01 python]# ./22.py
[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]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]
[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]
[1, 13, 78, 286, 715, 1287, 1716, 1716, 1287, 715, 286, 78, 13, 1]
[1, 14, 91, 364, 1001, 2002, 3003, 3432, 3003, 2002, 1001, 364, 91, 14, 1]
[root@mantisbt01 python]#

>> from collections import Iterable
>> isinstance([],Iterable)
True
>> isinstance({},Iteranle)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'Iteranle' is not defined
>> from collections import Iterable
>> isinstance([],Iterable)
True
>> isinstance({},Iterable)
True
>> isinstance('abc',Iterable)
True
>> isinstance(x for x in range(10),Iterable)
File "<stdin>", line 1
SyntaxError: Generator expression must be parenthesized if no t sole argument
>> isinstance((x for x in range(10)),Iterable)
True
>> isinstance(100,Iterable)
False
>>
>> from collections import Iterator
>> isinstance((x for x in range(10)),Iterator)
True
>> isinstance([],Iterator)
False
>> isinstance({},Iterator)
False
>> isinstance('ABC',Iterator)
False
>> isinstance(100,Iterator)
False
>> isinstance(iter([]),Iterator)
True
>> isinstance(iter('abc'),Iterator)
True
>>
>>
>> for x in [1,2,3,4,5]:
... pass
...
>> for x in [1,2,3,4,5]:
... print(x)
...
1
2
3
4
5
>>
>>
>> it=iter([1,2,3,4,5])
>> while True:
... try:
... x=next(it)
... print(x)
... except StopIteration:
... break
...
1
2
3
4
5
>>

凡是可作用於for循環的對象都是Iterable類型;

凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;

集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。

函數式編程

函數式編程就是一種抽象程度很高的編程範式,純粹的函數式編程語言編寫的函數沒有變量,因此,任意一個函數,只要輸入是確定的,輸出就是確定的,這種純函數我們稱之爲沒有副作用。而允許使用變量的程序設計語言,由於函數內部的變量狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函數是有副作用的。

函數式編程的一個特點就是,允許把函數本身作爲參數傳入另一個函數,還允許返回一個函數!

Python對函數式編程提供部分支持。由於Python允許使用變量,因此,Python不是純函數式編程語言。

1.高階函數

傳入函數
既然變量可以指向函數,函數的參數能接收變量,那麼一個函數就可以接收另一個函數作爲參數,這種函數就稱之爲高階函數。

一個最簡單的高階函數:

>> abs
<built-in function abs>
>> abs(-10)
10
>> x=abs(-2)
>> x
2
>> f=abs
>> f
<built-in function abs>
>> f(-2)
2
>> abs=10
>> abs
10
>> abs(-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

[root@mantisbt01 python]# python
Python 3.6.4 (default, Mar 19 2018, 10:30:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-16)] on linux
Type "help", "copyright", "credits" or "license" for more information.

>> abs(-2)
2
>> f(-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'f' is not defined
>> f=abs
>> f(-2)
2
>> def add(x,y,f):
... return f(x) + f(y)
...
>> print(add(-5,6,abs))
11

map\reduce

>> abs(-2)
2
>> f(-2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'f' is not defined
>> f=abs
>> f(-2)
2
>> def add(x,y,f):
... return f(x) + f(y)
...
>> print(add(-5,6,abs))
11
>>
>>
>> def f(x):
... return x*x
...
>> r=map(f,[1,2,3,4,5,6,7,8,9])
>> list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>> r
<map object at 0x7fa94a74ce10>
>>
>> L=[]
>> for n in [1,2,3,4,5,6,7,8,9]:
... L.append(f(n))
...
>> print(L)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
>>

>> from functools import reduce
>> def add(x,y):
... return x+y
...
>> reduce(add,[1,3,5,7,9])
25
>>
>> from functools import reduce
>> def fn(x,y):
... return x*10+y
...
>> reduce (fn,[1,3,5,7,9])
13579
>>

>> from functools import reduce
>> def fn(x,y):
... return x*10+y
...
>> def char2num(s):
... digits = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
... return digits[s]
...
>> reduce (fn,map(char2num,'13579'))
13579
>>

整理成一個函數

>> from functools import reduce
>> DIGITS = {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
>> def str2int(s):
... def fn(x,y):
... return x*10+y
... def char2num(s):
... return DIGITS[s]
... return reduce(fn,map(char2num,s))
...
>> print(str2int('13579'))
13579
>>

>> from functools import reduce
>> DIGTS={'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
>> def char2sum(s):
... return DIGITS[s]
...
>> def str2int(s):
... return reduce(lambda x,y:x*10+y,map(char2num,s))
...
>>
>>
>>
>> str2int('13579')
13579
>> str2int('1239')
1239
>>

利用map()函數,把用戶輸入的不規範的英文名字,變爲首字母大寫,其他小寫的規範名字。輸入:['adam', 'LISA', 'barT'],輸出:['Adam', 'Lisa', 'Bart']:

>>
>> def normalize(name):
... name=name[0].upper()+name[1:].lower()
... return name
...
>> L1=['adam','LISA','BarT']
>> Ls=list(map(normalize,L1))
>> print(Ls)
['Adam', 'Lisa', 'Bart']
>>
>>
>> def normalize2(name):
... name=name.lower()
... name=name.upper()
... return name
...
>> L1=['adam','LISA','BarT']
>> L2=list(map(normalize2,L1))
>> print(L2)
['ADAM', 'LISA', 'BART']
>>
>>
>> def normalize3(name):
... return name.capitalize()
...
>> L2=list(map(normalize3,L1))
>> print(L2)
['Adam', 'Lisa', 'Bart']
>> L1=['adam','LISA','BarT']
>> L2=list(map(normalize3,L1))
>> print(L2)
['Adam', 'Lisa', 'Bart']
>>

Python提供的sum()函數可以接受一個list並求和,請編寫一個prod()函數,可以接受一個list並利用reduce()求積:

>> def prod(L):
... def fn(x,y):
... return xy
... return reduce(fn,L)
...
>> print('3
579=',prod([3,5,7,9]))
357*9= 945
>> if prod([3,5,7,9])==945:
... print('測試成功!')
... else:
... print('測試失敗!')
...
測試成功!
>>
>>

利用map和reduce編寫一個str2float函數,把字符串'123.456'轉換成浮點數123.456:

>> from functools import reduce
>> def str2float(s):
... def fn(x,y):
... return x*10+y
... n=s.index('.')
... s1=list(map(int,[x for x in s[:n]]))
... s2=list(map(int,[x for x in s[n+1:]]))
... return reduce(fn,s1) + reduce(fn,s2)/10**len(s2)
... print('str2float(\'123.456\') =', str2float('123.456'))
...
>>
>> print('str2float(\'123.456\') =', str2float('123.456'))
str2float('123.456') = 123.456
>>
>> if abs(str2float('123.456') - 123.456) < 0.00001:
... print('測試成功!')
... else:
... print('測試失敗!')
...
測試成功!
>>

>> print('str2float(\'1.43\') =', str2float('1.43'))
str2float('1.43') = 1.43
>>
>>

filter

用filter求素數
計算素數的一個方法是埃氏篩法,它的算法理解起來非常簡單:

首先,列出從2開始的所有自然數,構造一個序列:

2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取序列的第一個數2,它一定是素數,然後用2把序列的2的倍數篩掉:

3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取新序列的第一個數3,它一定是素數,然後用3把序列的3的倍數篩掉:

5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

取新序列的第一個數5,然後用5把序列的5的倍數篩掉:

7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...

不斷篩下去,就可以得到所有的素數。

>> def is_odd(n):
... return n%2 ==1
...
>> list(filter(is_odd,[1,2,4,6,9,10]))
[1, 9]
>> list(filter(is_odd,[1,2,4,5,6,9,10,15]))
[1, 5, 9, 15]
>>
>> def not_empty(s):
... return s and s.strip()
...
>> list(filter(not_empty,['A','','B',None,'C',' ']))
['A', 'B', 'C']
>>
>>
>>
>>
>>
>> def _odd_iter():
... n=1
... while True:
... n=n+2
... yield n
...
>>
>>

>> def primes():
... yield 2
... it = _odd_iter()
... while True:
... n=next(it)
... yield n
... it=filter(_not_divisible(n),it)
...
>>
>> for n in primes():
... if n < 1000:
... print(n)
... else:
... break
...
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
101
103
107
109
113
127
131
137
139
149
151
157
163
167
173
179
181
191
193
197
199
211
223
227
229
233
239
241
251
257
263
269
271
277
281
283
293
307
311
313
317
331
337
347
349
353
359
367
373
379
383
389
397
401
409
419
421
431
433
439
443
449
457
461
463
467
479
487
491
499
503
509
521
523
541
547
557
563
569
571
577
587
593
599
601
607
613
617
619
631
641
643
647
653
659
661
673
677
683
691
701
709
719
727
733
739
743
751
757
761
769
773
787
797
809
811
821
823
827
829
839
853
857
859
863
877
881
883
887
907
911
919
929
937
941
947
953
967
971
977
983
991
997
>>

回數是指從左向右讀和從右向左讀都是一樣的數,例如12321,909。請利用filter()篩選出回數:

>> def is_palindrome(n):
... if str(n)==str(str(n)[::-1]):
... return n
...
>> out=filter(is_palindrome,range(1,1000))
>>
>> print('1~1000:',list(out))
1~1000: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555, 565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787, 797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]
>> out=filter(is_palindrome,range(1,200))
>> print('1~200:',list(out))
1~200: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]
>>

貌似不能判斷最後一個元素

>> out=filter(is_palindrome,1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>> out=filter(is_palindrome,range(1))
>> print('1:',list(out))
1: []
>> out=filter(is_palindrome,range(1,2))
>> print('1:',list(out))
1: [1]
>> out=filter(is_palindrome,range(1,3))
>> print('1~3:',list(out))
1~3: [1, 2]
>> out=filter(is_palindrome,range(1,11))
>> print('1~3:',list(out))
1~3: [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> out=filter(is_palindrome,range(1,12))
>> print('1~3:',list(out))
1~3: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
>>

法2

>> def is_palindrome(n):
... a=list(str(n))
... b=list(str(n))
... b.reverse()
... return a==b
...
>>
>> out=filter(is_palindrome,range(1,11))
>> print('1~3:',list(out))
1~3: [1, 2, 3, 4, 5, 6, 7, 8, 9]
>> out=filter(is_palindrome,range(1,12))
>> print('1~3:',list(out))
1~3: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]
>>
>> a=range(1,5)
>> a
range(1, 5)
>> list(a)
[1, 2, 3, 4]
>>
>>
>>

sorted

>> sorted([2,4,-6,21,9])
[-6, 2, 4, 9, 21]
>> sorted([2,4,-6,21,-9])
[-9, -6, 2, 4, 21]
>> sorted([2,4,-6,21,-9,0])
[-9, -6, 0, 2, 4, 21]
>> sorted([2,4,-6,21,-9,0],key=abs)
[0, 2, 4, -6, -9, 21]
>> sorted(['Bob','about','Zoo','Credit','kel'])
['Bob', 'Credit', 'Zoo', 'about', 'kel']
>>

>> sorted(['bob','about','Zoo','Credit'],key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
>>
>> sorted(['bob','about','Zoo','Credit'],key=str.lower,reverse=True)
['Zoo', 'Credit', 'bob', 'about']
>>

>> L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]

按分數排序

>> sorted(L,key=lambda x:x[1])
[('Bart', 66), ('Bob', 75), ('Lisa', 88), ('Adam', 92)]

按名字排序

>> sorted(L,key=lambda x:x[0])
[('Adam', 92), ('Bart', 66), ('Bob', 75), ('Lisa', 88)]
>>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章