python学习笔记(3)
每日一博
《python编程快速上手》第
第三章:函数
1.
def hello(): print('Howdy!') print('Howdy!!!') print('Hello there') hello() hello() hello()
第一行是一个def语句,定义了一个名为hello()的函数。def之后的代码块是函数体,这段代码在调用的时候才会执行,而不是在第一次定义的时候执行。函数之后的语句行就是进行函数的调用。在代码中,函数调用就是函数名跟上括号名,也许在括号名之间有一些参数。
2.def语句和参数
如果调用print()或者len()函数,会传入参数。当然也可以自己定义接收参数的函数
def hello(name): print('Hello'+name) hello('Alice') hello('Bob') hello('Alice') hello('Bob')
这个程序最终运行的结果是:
Hello Alice
Hello Bob
3.返回自和return 语句
一般来讲,函数调用求值的结果,称之为"返回值"
return 语句包含以下几个部分:
(1)return 关键字
(2)函数应该返回的值或者表达式
4.None值
Python中有一个值称为None,它表示没有值,None就是NoneType数据类型的唯一值,就像布尔值True和False一样,None必须首字母大写
5.关键字参数和print()
(1)print()函数在字符串末尾自动添加了换行符,但是可以设置end参数,将其变为一个字符串,例如:
print('Hello',end=' ')
print('World')
print('Hello',end=' ') print('World') 打印出Hello world
(2)print()传入多个字符串值,print()函数会自动用一个空格将其分开
print('cat','dog','mice')
//cats dogs mice
6.局部和全局的作用域
(1)局部作用域:在被调用函数内部赋值的变元或者变量
(2)全局作用域:在所有函数之外赋值的变量
(3)局部变量:处于局部作用域中的变量
(4)全局变量:处于全局作用域中的变量
一个变量必须是其中的一种,不可嫩既是全局变量又是局部变量
(5)作用域可以看做是变量的容器,作用域被摧毁的时候,保存在作用域中的变量值就被丢弃了。全局作用域是在程序开始的时候创建的,如果程序终止,全局作用域就被销毁,全局变量就会被丢弃
(6)一个函数在被调用的时候,就创建了一个局部作用域。在这个函数内部赋值的所有变量,存在于该局部作用域的内部。在函数返回的时候,这个局部作用域就被销毁了,这个变量就丢失了,在下次调用的时候,局部变量不会记得该函数上次被调用的时候他们保存的值。
(7)作用域很重要,理由如下:
全局作用域中的代码不能使用任何局部变量;
但是局部变量可以访问全局变量
函数局部作用域中的代码,不能使用其他局部作用域中的代码
如果在不同的作用域中,可以使用相同名字命名不同的变量,也是说可以命名一个名字为spam的局部变量和一个全名为spam的全局变量
(8)局部变量不能再全局作用域内使用
def spam(): eggs=31337 spam() print(eggs) #这里将会报错,因为eggs变量只属于spam()调用所创建的局部作用域。在程序从spam()返回之后,这个局部作用域就会别销毁
不再有eggs变量,所以当程序执行print(eggs)时候,python就会报错,说eggs没有被定义
(9)局部作用域不能使用其他局部作用域定义的变量
def spam(): eggs=99 bacon() print(eggs) def bacon(): ham=101 eggs=0 spam()
#程序开始的时候spam()函数被调用,创建了一个局部函数作用域,局部变量eggs被赋值为99,然后bacon()函数被调用
创建了第二个局部作用域,多个局部作用域同时存在,在新的局部作用域中,局部变量ham被赋值为101,局部变脸eggs(与spam()的局部作用域中的那个变量不同)也被创建,并且赋值为0
当bacon()返回的时候,这次调用的局部作用域被销毁,程序在spam()中继续执行,打印出eggs的值。因为spam()调用的局部作用域仍然存在,eggs变量被赋值为99。这个地方的要点在于,一个函数中的局部变量与其他函数的局部变量分隔开来
(10)全局变量可以在局部作用域中进行相关的读取
def spam(): print(eggs) eggs=42 spam() print(eggs)
因为在spam()函数汇总,没有变元名为eggs,也没有代码为eggs赋值,所以当spam()中使用eggs的时候,Python认为是对全局变量eggs的引用,这就是前面的程序运行的时候打印出42的原因
(11)名称相同的局部变量和全局变量
要想生活简单,就要避免局部变量和全局变脸或者其他全局变量的名称相同。但是在技术上,让局部变量和全局变量的名称相同是完全合法的。
def spam(): eggs='spam local' print(eggs) def bacon(): eggs='bacon loca' print(eggs) spam() print(eggs) eggs='global' bacon() print(eggs)
#
在这个程序中,实际上有 3 个不同的变量,但令人迷惑的是,它们都名为 eggs。
这些变量是:
名为 eggs 的变量,存在于 spam()被调用时的局部作用域;
名为 eggs 的变量,存在于 bacon()被调用时的局部作用域;
名为 eggs 的变量,存在于全局作用域。
因为这 3 个独立的变量都有相同的名字,追踪某一个时刻使用的是哪个变量,
可能比较麻烦。这就是应该避免在不同作用域内使用相同变量名的原因。
第四章、列表
1.列表数据类型
(1)列表是一个值,包含多个字构成的序列。列表值指的是列表本身,而不是指列表值之内的那些值,列表值看起来像:['cat','bat','rat','elephant'],列表中的值也称为表项,表项用逗号进行分隔。[]是一个空列表,不包含任何值类似于空字符串
(2)用下标取得列表的单个值。假定列表spam=['cat','bat','rat','elephant']。那么在python中spam[0]='cat',spam[1]=bat,spam[2]='rat',spam[3]='elephant'
(3)如果使用的下表超过了列表中值的个数,Python将会给出IndexError的出错信息
(4)下标只能是整数,不能是浮点值
(5)列表也可以包含其他列表的值,可以通过多重下表来进行相关的访问,第一个下标使用哪个列表,第二个下标表明使用列表中的值
(6)负数下标
虽然下标是从0开始向上增长的,但是也可以用负整数作为下标,整数值-1表示列表中随后一个元素的下标,-2表示倒数第二个元素的下标,以此类推
(7)利用切片获取子列表
切片输入在一对方括号中,由冒号分隔的两个整数
spam[2]是一个列表和一个下标(一个整数)
spam[1:4]是一个列表和一个切片(两个整数)(注意:切片是一个左闭右开的区间)
作为快捷方法,可以省略切片汇总冒号两边的两个下标,省略第一个下标相当于使用0,或者列表的开始;省略第二个下标相当于使用了列表的长度,意味着分片直至列表的末尾
(8)使用len()函数获取列表的长度:len()函数将返回传递给它的列表中的值的个数,就像计算字符串中字符的个数一样。
(9)使用下改变列表中的值:spam[1]='aardvark'意味着将spam下标1处的值赋值为字符串aardvark
(10)列表的连接和列表的复制
+操作符可以连接两个列表,得到一个新的列表,就像两个字符串合并为一个新的字符串一样;*操作符可以用于一个列表和一个整数,实现列表的复制
(11)del语句从列表中删除值
del语句将删除列表中下标处的值,表中被删除值后面的所有值都将向前移动一个下标。
2.使用列表。下面这个例子可以使用列表来保存用户输入的任意多的猫
catNames=[] while True: print('Enter the name of cat '+str(len(catNames)+1)+'(Or enter nothing to stop.):') name=input() if name== '': break; catNames=catNames+[name] #list concatention print('the cat names are:') for name in catNames: print(' '+name)
#使用列表来不断添加元素
(1)以下这两种表示列表的方式相同
for i in range(4): print(i) for i in [0,1,2,3]: print(i)
在python中常见的一个技巧:是在for循环中使用range(len(someList)),迭代列表中的每一个下标,如
supplies = ['pens','staplers','flame-throwers','binders'] for i in range(len(supplies)): print('Index'+str(i)+'in supplies is:'+supplies[i])
在前面的循环汇总使用range(len(supplies))很方便,因为可以直接使用下标值来进行直接的访问
(2)in 和 not in 操作符
利用in和not in 操作符,可以确定一个值是否在列表中,in和not in一样,在表达式中用于连接两个值:一个要在列表中查找的值,以及要查找的列表
(3)多重赋值的技巧
3.增强的赋值操作:
(1)
增强的赋值操作 等价的赋值操作
sparm+=1 sparm=sparm+1
sparm-=1 sparm=sparm-1
sparm*=1 sparm=sparm*1
sparm/=1 sparm=sparm/1
sparm%=1 sparm=sparm%1
+=操作符也可以完成字符串和列表的连接,*=可以用于完成字符串和里诶博爱的复制
4.方法
(1)用index()方法在列表中查找值,列表值有一个index()方法,可以传入一个值,如果这个值存储在列表中,那就返回它的下标,如果不在列表中,那么python就会报ValueError。如果列表中存在重复值,那就是返回第一次出现的下标
>>> spam 42 >>> spam=['hello','hi','howdy','heyas'] >>> spam.index('hi') 1 >>> spam.index('hello') 0 >>> spam.index('heyas') 3 >>>
(2)用append()方法和inser()方法在列表中添元素,要在列表中增加新值,那就需要用到append()方法和insert()方法,将参数添加到列表的末尾;而insert()方法可以在任意出插入一个值,Insert()方法第一个参数是新值的下标,第二个参数是要插入的新值
(3)用remove()方法从列表中删除元素
['chicken', 'hello', 'hi', 'howdy', 'heyas', 'cat'] >>> spam.remove('hello') >>> spam ['chicken', 'hi', 'howdy', 'heyas', 'cat']
试图删除列表中不存在的值,会导致ValueError错误
(4)用sort()方法将列表中的值进行排序:数值的列表或者字符串的列表,都能用sort()方法进行排序
>>> spam=[2,5,1,3.14,9,-9] >>> spam.sort() >>> spam [-9, 1, 2, 3.14, 5, 9]
对字符串进行排序
>>> spam=['ants','cat','dogs','badgers','elephants'] >>> spam ['ants', 'cat', 'dogs', 'badgers', 'elephants'] >>> spam.sort() >>> spam ['ants', 'badgers', 'cat', 'dogs', 'elephants']
这个地方也可以指定reverse关键字的参数为True,让sort()按照逆序进行相关的排序。
>>> spam.sort(reverse=True) >>> spam ['elephants', 'dogs', 'cat', 'badgers', 'ants']
6.类似类表的类型:字符串和数组
(1)类表并不是唯一表示序列值的数据类型。只要你认为字符串是单个文本字符的列表,对列表的许多操作,也可以用于字符串
>>> name='Zoophie' >>> name[0] 'Z' >>> name[-2] 'i' >>> name[0:2] 'Zo'
7.可变与不可变的数据类型
(1)列表是一个可变的数据类型,它的值可以添加、删除或者改变。但是字符串是不可变的,它不能被更改。尝试对字符串中的一个字符重新复制,将导致TypeError错误。
改变一个字符串的正确方式,是使用切片和连接。构造一个新的字符串,从老的字符串哪里复制一部分
>>> name='Zophie a cat' >>> newName=name[0:7]+'the'+name[8:12] >>> name 'Zophie a cat' >>> newName 'Zophie the cat'
(2)元组数据类型
除了这两个方面之外,元组数数据类型和列表数据类型一样。
1)元组输入时用圆括号()而不是用方括号[]
2)元组合字符串一样,是不可以改变的,元组不能让他们的值被修改、删除或者添加
8.用list()和tuple()函数来实现类型的转换
如str(42)将返回'42',就是将整数42转换为字符串的表示形式,函数list()和tuple()将返回传递给他们的值的列表和元组版本。
>>> tuple(['cat','dog',5]) ('cat', 'dog', 5)
#返回的是元组类型
>>> list(('cat','dog',5))
['cat', 'dog', 5]
#这个是将元组转换成类表的类型
9.引用。创建列表的时候,将其引用赋值给了变量,但是cheese=spam只是将spam中的列表拷贝到了cheese,而不是列表本身。这就意味着存储在spam和cheese中的值,现在指向了同一个列表,底下只有一个列表,因为列表本身从未复制,所以从你修改cheese变量的第一个元素的时候,也修改了spam指向的列表
[0, 'hello', 2, 3, 4, 5] >>> spam=[0,1,2,3,4,5,6] >>> cheese=spam >>> cheese[1]='hello' >>> cheese [0, 'hello', 2, 3, 4, 5, 6] >>> spam [0, 'hello', 2, 3, 4, 5, 6]
4.7.1传递引用
第五章 字典和结构化数据
1.字典数据类型
(1)字典是许多值的集合。但是不像列表的下标,字典的索引可以使用许多不同的数据类型,不只是整数。字典的索引被称之为"键",键及其关联的值称之为"键值对"。字典的输出是带花括号的。
myCat={'size':'fat','color':'gray','disposition':'loud'}
(2)字典与列表:与列表不同,字典中的表项是不排序的。名为spam的列表中,第一个表项是spam[0],但是字典中没有"第一个"表项。虽然确定两个表是否相同的时候,表项顺序很重要,但是在字典中键值对的顺序并不重要;字典是不排序的,所以不能像列表那样进行切片操作
(3)keys(),value()和items()方法
keys() 返回字典的键
values() 返回字典的值
items() 返回字典的键值对
spam = {'color':'red','age':42} for v in spam.values(): print(v)
#这里通过for循环迭代了spam字典中的每个值
for循环迭代spam字典中的每个键
for k in spam.keys(): print(k)
for循环迭代字典中的每个键值对
for i in spam.items(): print(i)
由上面的几个方法可以看到,通过keys(),values()和items()方法,循环分别可以迭代键、值、或者键值对。请注意:items()方法返回的dict_items值中,包含的是键和值的元组
(4)检查字典中是否存在键或者值
spam={'name':'Zophie','age':7} #这里判断'name'是否在所有的键中 print('name' in spam.keys()) print('Zophie' in spam.values()) print('color' in spam.values()) print('color' not in spam.keys()) print('color' in spam)