python 学习简记 《编程导论》 CH4&CH5

《编程导论》 CH4 函数、作用域和规范抽象

4.1 函数和作用域

1.函数定义形式:

def name of function( list of formal parameters):

      body of function         

例如:

def max(x,y):
    if x > y:
        return x
    else:
        return y
2.关键字参数和默认值
       形参绑定到实参两种方式:位置参数(第一个形参被绑定到第一个实参,第二个形参被绑定到第二个实参,依次类推)、关键字参数(形参根据名称绑定到实参 如:max(y=27,x=23))

关键字参数可以在实参列表中以任意顺序出现,但关键字参数之后不能为非关键字参数

关键字参数常和参数默认值结合起来。

def printName(firstName,lastName,reverse = False):

    if reverse :

         print lastName + ', '+firstName

    else:

         print firstName,lastName

使用默认值可以在调用函数时不传入所有参数

3.作用域

4.2 规范

三引号之间的文本在Python中被称为文档字符串。可以通过内建函数help查看

规范=条件+功能 是函数编写者与使用者之间的约定。

def findRoot(x,power,epsilon):
    """Assumes x and epsilon int or float,power an int,
        eplison >0 & power >=1
    Returns float y such that y**power is within epsilon of x,
        If such a float does not exist, it returns None"""
    low=min(-1.0,x)
    high=max(1.0,x)
    ans=(high+low)/2.0
    while abs(ans**power-x)>=epsilon:
        if ans**power 
4.4 全局变量
def fib(x):
    """asuume x is an int which >0
        return xth fib num"""
    global numFibCalls
    numFibCalls+=1
    if x == 0 or x == 1:
        return 1
    else:
        return fib(x-1) + fib(x-2)

def testFib(n):
    for i in range(n+1):
        global numFibCalls
        numFibCalls = 0
        print 'fib of',i,'=',fib(i)
        print 'fib called',numFibCalls,'times.'

testFib(1)
testFib(2)
testFib(3)

运行结果如下:

fib of 0 = 1
fib called 1 times.
fib of 1 = 1
fib called 1 times.
fib of 0 = 1
fib called 1 times.
fib of 1 = 1
fib called 1 times.
fib of 2 = 2
fib called 3 times.
fib of 0 = 1
fib called 1 times.
fib of 1 = 1
fib called 1 times.
fib of 2 = 2
fib called 3 times.
fib of 3 = 3
fib called 5 times.


4.5 模块

一个模块是包含Python定义和语句的.py文件。

程序可以通过import语句来访问一个模块。

模块一般存储在单独的文件中,每个模块有自己的私有符号表,在模块内可以使用通常方式访问对象。

执行import M会在发生导入操作的作用域中创建一个指向模块M的引用。导入上下文中使用点标记发来使用定义在被导入模块中的名称。

在一个解释器会话中一个模块只被导入一次,运行reload()语句可以强制解释器重新导入所有模块。


4.6 文件

使用文件句柄来访问文件。

例如:

nameHandle = open('kids','a')
nameHandle.write('David\n')
nameHandle.write('Andrea\n')
nameHandle.close()
nameHandle=open('kids','r')
for line in nameHandle:
    print line[:-1]
nameHandle.close()
常用文件操作:

open(fn,'w') 创建一个文件用于写入内容

open(fn,'r') 打开一个已有文件用于读取内容

open(fn,'a') 打开一个已有文件用于追加内容

fh.read() 返回一个包含文件内容的字符串

fh.readline() 返回文件的下一行

fh.readlines() 返回一个列表,其中的一个元素就是文件的一行

fh.write(s) 将字符串s写到文件结尾

fh.writeLines(S) S是一个字符串序列,这条语句会将S的每个元素都写入文件

fh.close() 关闭文件


CH5  结构化类型、可变性和高阶函数

5.1 元组

元组是元素的有序序列。

注:要想表示包含整数1的元组,需要写成(1,)而不是(1),后者仅是整数1的复杂写法

元组可以被组合、索引和切片

例如:

t1=(1,'two',3)
t2=(t1,3.25)
print t2
print (t1+t2)
print (t1+t2)[3]
print (t1+t2)[2:5]
for语句可以用来遍历元组中的元素。下面代码可以输出20和100的公约数并求所有公约数的和
#find divisor of 20 and 100
def findDivisors(n1,n2):
    divisors=()
    for i in range(1,min(n1,n2)+1):
        if n1%i==0 and n2%2==0:
            divisors=divisors+(i,)
    return divisors
divisors = findDivisors(20,100)
print divisors
total=0
for d in divisors:
    total += d
print total
序列和多重赋值

若已知一个序列(元组或字符串)长度,可以使用多重赋值语句来提取出单个元素。

如 x,y=(3,4)   a,b,c='xyz'


5.2 列表和可变性

列表字面量写法使用方括号,空列表写作[],只包含一个元素的列表不用加逗号。

列表与元组的一个重要区别是列表是可变的。而元组、整数、浮点数、字符串类型是不可变的。

无意形成的别名可能会导致难以追踪的程序错误。

列表的一些操作:

操作符+:会创建一个新列表连接原来的两个列表并返回

L.append(e) 将对象e添加到L的结尾

L.count(e) 返回L中e出现的次数

L.insert(i,e) 将对象e插入到L中下标为i的地方

L.extend(L1) 将列表L1中的元素添加到L的结尾

L.remove(e) 从L中删除第一次出现的e

L.index(e) 返回L中e第一次出现的下标。若e不再L中,将会引发一个异常

L.pop(i) 删除并返回下标为i的元素。如果i被省略,默认值是-1

L.sort() 有副作用地排序L中的元素

L.reverse() 有副作用地反转列表L


1.克隆

在遍历列表时应避免对其修改

可以使用切片来克隆列表 如 for e1 in L1[:]

另外表达式list(l)会返回列表l的一个副本

若被复制的列表包含可变对象,可以导入标准库copy并使用函数copy.deepcopy

2.列表解析

列表解析式一个能够将一种操作应用到序列中每一个值的简明方式。如

L=[x**2 for x in range(1,7)]

print L

将输出以下列表:

[1,4,9,16,25,36]


5.3 函数对象

Python中,函数是一等对象。函数有类型,如type(fact)的值是;函数可以出现在表达式中,如出现在赋值语句的右侧或者当作另一个函数的参数;函数可以当作列表的元素等。

在合并列表时,把函数当作参数是非常有用的。这样的编码风格称作高级编程。

例如:

def applyToEach(L,f):
    """assume L is a list and f is a function
        use f to each element in l,and use the return value to
            replace the old one"""
    for i in range(len(L)):
        L[i]=f(L[i])

L=[1,-2,3.33]
print 'L=',L
applyToEach(L,abs)
print 'L=',L
applyToEach(L,int)
print 'L=',L

结果如下:

L= [1, -2, 3.33]
L= [1, 2, 3.33]
L= [1, 2, 3]

函数applyToEach称高阶函数,因为其参数之一是函数。

Python的内建高阶函数map:第一个参数可以是n元函数,之后的参数可以是n个有序集合。

如 L1=[1,28,36]

L2=[2,57,9]

print map(min,L1,L2)

输出:[1,28,9]


5.4 字符串、元组和列表

字符串、元组和列表都属于序列类型。序列类型的常用操作:

seq[i] 返回序列中的第i个元素

len(seq) 返回序列的长度

seq1+seq2 将两个序列连接起来

n*seq 重复序列n遍

seq[start:end] 返回序列的一个分片

e in seq 判断e是否在序列中

e not in seq 判断e是否不在序列中

for e in seq 遍历序列中的元素

对比:

类型 元素类型 字面量示例 可变性
字符串 字符 '','a','abc' 不可变
元组 任意类型 (),(3,),('abc',4) 不可变
列表 任意类型 [],[3],['abc',4] 可变

字符串的一些方法:

s.count(s1) 统计s中s1出现的次数

s.find(s1) 返回s1在s中第一次出现的下标,若s1不在s中,返回-1

s.rfind(s1) 和find类似,但是从s的结尾开始

s.index(s1) 和find类似,但是若s1不在s中会抛出异常

s.rindex(s1) 和index类似,但是从s的结尾开始

s.lower() 将所有大写字母转换成小写字母

s.replace(old,new) 将s中所有的old字符串替换成new字符串

s.rstrip() 删除s结尾的空白符

s.split(d) 使用d作为分界来分割s。返回s的子字符串列表。若省略d使用空白符(空格,制表符,换行符,回车和换页符)来分割字符串


5.5 字典(dict)

原理同哈希,键值对的集合。字面量使用大括号包裹,每个元素的写法是一个键、一个冒号和一个值。

如:

monthNumbers = {'Jan':1,'Feb':2,'Mar':3,'Apr':4,'May':5,1:'Jan',2:'Feb',3:'Mar',4:'Apr',5:'May'}
print 'The third month is '+ monthNumbers[3]
dist=monthNumbers['Apr']-monthNumbers['Jan']
print 'Apr and Jan are',dist,'months apart'

输出:

The third month is Mar
Apr and Jan are 3 months apart

字典中实体无序,不能通过下标访问

monthNumbers.keys()返回包含字典所有键的列表,顺序无定义

使用for语句来遍历字典时,循环变量是键而非键值对

字典是可变的

常用的字典操作:

len(d) 返回d中项的数量

d.keys() 返回一个列表,包含d中的键

d.values() 返回一个列表,包含d中的值

k in d 若键k在d中返回true

d[k] 返回d中键为k的项

d.get(k,v) 若k在d中返回d[k]否则返回v

d[k]=v 将值v与键k关联起来。若键k已经关联到其他值,使用新值代替k

del d[k] 从d中删除键k

for k in d 遍历d中的键

任何不可变类型的对象都可作为字典的键

你可能感兴趣的:(python 学习简记 《编程导论》 CH4&CH5)