一、python基础
1、python中的两个数学操作符区分
操作符 | 操作 | 例子 | 求值为 |
---|---|---|---|
// | 整除/商数取整 | 22//8 | 2 |
/ | 除法 | 22/8 | 2.75 |
2、字符串复制
在用于两个整形或浮点型值时,* 操作符表示乘法。但 * 操作符用于一个字符串值和一个整型值时,它变成了“字符串复制”操作符:
>>> 'Alice' * 3
'AliceAliceAlice'
*操作符只能用于两个数字(作为乘法)。或一个字符串和一个整型(作为字符串复制操作符),否则,会报错。
3、使用IDLE创建程序
交互式环境对于一次运行一条指令很好,但编写完整的python程序,需要在文本编辑器中输入指令。在IDLE中打开文本编辑器,选择file->new window/new file,在交互式环境中按回车就会执行python指令,但在文本编辑器中允许输入多行指令,保存为文件,并运行该程序,下面是两者区别:
- 交互式环境窗口总是有>>>提示符。
- 文本编辑器窗口没有>>>提示符。
输入源代码之后进行保存,选择run->run module来运行程序。
4、常用python指令
- 注释— # 标志后面的所有文本都是注释。
- print()函数—内容显示,还可以用它来打印出空行,只要调用print()就可以了。
- input()函数—等待用户在键盘上输入文本,并按下回车键。此函数总是返回一个字符串,即使用户输入的是一个数字。
- len()函数—传递一个字符串(或包含字符串的变量),然后求值为一个整型值,即字符串中字符的个数。
- str()、int()、float()函数—这三个函数分别求值为传入值的字符串、整数和浮点数形式:
>>> str(0)
'0'
>>> str(-3.14)
'-3.14'
>>> int('42')
42
>>> int('-99')
-99
>>> int(1.15)
1
>>> int(1.99)
1
>>> float('3.14')
3.14
>>> float(10)
10.0
print()允许传入一个整型值或字符串,但如果在交互式环境中输入以下就会报错:
>>> print('I am '+ 29 + 'years old.')
Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
print('I am '+ 29 + 'years old.')
TypeError: can only concatenate str (not "int") to str
报错是因为,只能用+操作符加两个整数,或连接两个字符串。不能让一个整数和一个字符串相加,这不符合python的语法。正确应该是先获得值’29’,它是29的字符串形式。如下:
>>> print('I am '+ str(29) + ' years old.')
I am 29 years old.
5、文本和数字相等判断
虽然数字的字符串值被认为与整型值和浮点型值完全不同,但整型值可以与浮点值相等。
>>> 42 == '42'
False
>>> 42 == 42.0
True
>>> 42 == 0042.0000
True
python认为字符串是文本,而整型值和浮点型都是数字。
二、控制流
1、布尔值
在作为python代码输入时,布尔值True和False不像字符串,两边没有引号,如果大小写不正确或者使用True和False作为变量名,python就会给出错误信息。
2、布尔操作符
三个布尔操作符(and、or和not)用于比较布尔值,他们将这些表达式求值为一个布尔值。
- and和or操作符总是接受两个布尔值(或表达式),所以被认为是二元操作符。
- not操作符只作用于一个布尔值(或表达式),求值为相反的布尔值。可以嵌套not操作符,虽然并不经常这样做。
>>> not True
False
>>> not not not not False
False
比较操作符(==、!=、<、>、<=、>=)求值为布尔值,就可以和布尔操作符一起在表达式使用。在所有算术和比较操作符求值后,python先求值not操作符,然后是and操作符,最后是or操作符。
3、代码块
可以根据代码行的缩进,知道代码块的开始和结束,代码块有3条规则:
- 缩进增加时,代码块开始。
- 代码块可以包含其他代码块。
- 缩进减少为零,或减少为外面包围代码块的缩进,代码块就结束了。
4、elif语句
- elif语句是“否则如果”,总是跟在if或另一条elif语句后面,它提供了另一个条件,仅在前面的条件为False时才检查该条件。
- 如果有一系列的elif语句,仅有一条或零条子句会被执行。一旦一个语句的条件为True,剩下的elif语句会自动跳过。所以对于elif语句,次序是很重要的。
- 还可以选择在最后的elif语句后面加上else语句,这种情况下,保证至少一个子句(且只有一个)会执行,如果每个if和elif语句中的条件都为False,就执行else子句。
5、break语句和continue语句
- 可以使用break语句提前跳出while循环子句,在代码中,break语句仅包含break关键字。
while True:
print('please type your name.')
name=input()
if name=='your name':
break
print('thank you')
#运行结果:
please type your name.
zy
please type your name.
ls
please type your name.
your name
thank you
- continue语句用于循环内部,如果程序执行遇到continue语句,就会马上跳回到循环开始处,重新对循环条件求值。
while True:
print('who are you?')
name=input()
if name!='Joe':
continue
print('hello,joe.what is the password?(it is a fish.)')
password=input()
if password=='swordfish':
break
print('Access granted.')
#运行结果:
who are you?
zy
who are you?
Joe
hello,joe.what is the password?(it is a fish.)
fish
who are you?
Joe
hello,joe.what is the password?(it is a fish.)
swordfish
Access granted.
- 如果陷在一个无限循环中或者是希望马上停止程序,即使它不是陷在无限循环中,那么请按Ctrl-C,这将向程序发送KeyboardInterrupt错误,导致它立即停止。
6、for循环和range()函数
如果想让一个代码块执行固定的次数,可以通过for循环语句和range()函数来实现。(其他数据类型中的某些值,条件认为它们等价于True和False,在用于条件时,0、0.0和' '被认为是False,其他值被认为是True。
print('my name is')
for i in range(5):
print('jimmy five times ('+str(i)+')')
#运行结果:
my name is
jimmy five times (0)
jimmy five times (1)
jimmy five times (2)
jimmy five times (3)
jimmy five times (4)
for语句让i增加1,变量i将递增到(但不包括)传递给range()函数的整数。
range()函数可以用三个参数调用,第一个参数是for循环变量开始的值,第二个参数是上限,但不包含它,也就是循环停止的数字,第三个参数是步长,就是每次迭代后循环变量增加的值。步长可以是负数,让循环计数逐渐减少,而不是增加。
for i in range(10,-6,-4):
print(i)
#运行结果:
10
6
2
-2
7、导入模块
在开始使用一个模块中的函数之前,必须用import语句导入该模块,如果导入多个模块,则之间用逗号隔开。
import random
for i in range(5):
print(random.randint(1,10))
#运行结果(不唯一):
9
6
5
7
4
开始导入random模块,random.randint()函数调用求值为传递给它的两个整数之间的一个随机整数,因为randint()属于random模块,必须在函数名称之前加上random。
import语句的另一种形式包括from关键字,之后是模块名称、import关键字和一个星号,例如from random import *。使用这种形式调用random模块中的函数时不需要random.前缀。但是,使用完整的名称会让代码更可读,所以推荐使用第一种。
8、sys.exit()
通过调用sys.exit()函数,可以让程序提前终止或退出,因为这个函数在sys模块中,所以必须先导入sys才能使用。
import sys
while True:
print('Type exit to exit.')
response=input()
if response=='exit':
sys.exit()
print('you typed '+response+'.')
#运行结果:
Type exit to exit.
no
you typed no.
Type exit to exit.
exit
>>>
三、函数
1、def语句和参数
如果调用print()或len()函数,会传入一些值,放在括号之间,在这里称为“参数”。
def hello(name):
print('hello '+name)
hello('Alice')
hello('Bob')
#运行结果:
hello Alice
hello Bob
2、None值
python中有一个值称为None,他表示没有值。None是NoneType数据类型的唯一值。有一个使用None的地方就是print()的返回值,print()函数在屏幕上显示文本,但他不需要返回任何值,但既然所有函数调用都需要求值为一个返回值,那么print()就返回None。
>>> spam=print('hello')
hello
>>> None==spam
True
3、关键字参数和print()
大多数参数是由它们在函数调用中的位置来识别的。但是,关键字参数是由函数调用时加在它们前面的关键字来识别的。关键字参数通常用于可选变元。例如,print()函数有可选变元end和sep,分别指定在参数末尾打印什么,以及在参数之间打印什么来隔开它们。
print('hello')
print('world')
#运行结果:
hello
world
这是因为print()函数自动在传入的字符串末尾添加了换行符。可以设置end关键字参数,将它变成另一个字符串。
print('hello',end='-')
print('world')
#运行结果
hello-world
类似的,如果向print()传入多个字符串值,该函数就会自动用一个空格分隔它们。
>>> print('cats','dogs','mice')
cats dogs mice
可以传入sep关键字参数,替换掉默认的分割字符串。
>>> print('cats','dogs','mice',sep=',')
cats,dogs,mice
4、局部和全局作用域
- 局部变量不能在全局作用域内使用。
- 局部作用域不能使用其他局部作用域内的变量。
def spam():
eggs=99
bacon()
print(eggs)
def bacon():
ham=101
eggs=0
spam()
#运行结果
99
- 全局变量可以在局部作用域中读取。
- python中让局部变量和全局变量同名是完全合法的。
def spam():
eggs='spam local'
print(eggs)
def bacon():
eggs='bacon local'
print(eggs)
spam()
print(eggs)
eggs='global'
bacon()
print(eggs)
#运行结果
bacon local
spam local
bacon local
global
5、global语句
如果需要在一个函数内修改全局变量,就使用global语句。如果在函数的顶部有global eggs这样的代码,就告诉python:在这个函数中,eggs指的是全局变量,所以不要用这个名字创建一个局部变量。
def spam():
global eggs
eggs='spam local'
eggs='global'
spam()
print(eggs)
#运行结果:
spam local
6、异常处理
错误可以由try和except语句来处理,那些可能出错的语句被放在try子句中,如果错误发生,程序执行就赚转到接下俩的except子句开始处。
def spam(divide):
try:
return 42/divide
except ZeroDivisionError:
print('Error:Invalid argument.')
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
#运行结果:
21.0
3.5
Error:Invalid argument.
None
42.0
在函数调用中的try语句块中,发生分所有错误都会被捕捉。一旦执行调到except子句的代码,就不会回到try子句。它会继续照常向下执行。
def spam(divide):
return 42/divide
try:
print(spam(2))
print(spam(12))
print(spam(0))
print(spam(1))
except ZeroDivisionError:
print('Error:Invalid argument.')
#运行结果:
21.0
3.5
Error:Invalid argument.
四、列表
1、列表数据类型
- “列表”是一个值。它包含多个字构成的序列。列表用左方括号开始,右方括号结束,即[ ],列表中的值也称为表项,表项用逗号分隔。
- 列表后面方括号内的整数被称为“下标”。列表中第一个值的下标是0,第二个值的下标是1,以此类推。下标只能是整数。
>>> spam=[['cat','bat'],[10,20,30,40,50]]
>>> spam[0]
['cat', 'bat']
>>> spam[0][1]
'bat'
>>> spam[1]
[10, 20, 30, 40, 50]
>>> spam[1][4]
50
-也可以用负整数作为下标,整数值-1指的是列表中的最后一个下标,-2指的是倒数第二个下标。以此类推。
>>> spam=['cat','bat','rat','elephant']
>>> spam[-1]
'elephant'
>>> spam[-3]
'bat'
- 可以利用“切片”从列表中取得多个值,结果是一个新列表。切片输入在一对方括号中,但它有两个用冒号分隔的整数,第一个整数是切片开始处的下标,第二个整数是切片结束处的下标,但不包含它。
>>> spam=['cat','bat','rat','elephant']
>>> spam[1:3]
['bat', 'rat']
>>> spam[0:-1]
['cat', 'bat', 'rat']
可以省略冒号两边的某个下标,省略第一个下标相当于使用0,或列表的开始,省略第二个下标相当于使用列表的长度,意味着分片直至列表的末尾。
>>> spam=['cat','bat','rat','elephant']
>>> spam[:2]
['cat', 'bat']
>>> spam[1:]
['bat', 'rat', 'elephant']
>>> spam[:]
['cat', 'bat', 'rat', 'elephant']
- 可以使用len()函数取得列表的长度。例如len(spam).。
- 可以使用列表的下标来改变下标处的值。例如spam[1]='dark'。
- +操作符可以连接两个列表,得到一个新列表,*操作符可以用于一个列表和一个整数,实现列表的复制。
>>> [1,2,3]+['A','B','C']
[1, 2, 3, 'A', 'B', 'C']
>>> ['X','Y','Z']*3
['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z']
>>> spam=[1,2,3]
>>> spam=spam+['B','P']
>>> spam
[1, 2, 3, 'B', 'P']
- del语句将删除列表中下标处的值,表中被删除值后面的所有值,都将向前移动一个下标。del语句也可以用于一个简单变量,删除它,作用相当于“取消赋值”语句。实践中,一般del语句总是用于删除列表中的值。
>>> spam=['cat','bat','rat','elephant']
>>> del spam[2]
>>> spam
['cat', 'bat', 'elephant']
>>> del spam[2]
>>> spam
['cat', 'bat']
2、使用列表
- 循环是针对一个列表或类似列表中的每个值,重复的执行代码块。常见的一个python技巧是在for循环中使用range(len(somelist)),迭代列表的每一个下标。
>>> for i in range(len(supplies)):
print('Index '+str(i)+' in supplies is:'+supplies[i])
Index 0 in supplies is:pens
Index 1 in supplies is:staplers
Index 2 in supplies is:flames
Index 3 in supplies is:binders
- 利用in和not in操作符,可以确定一个值是否在列表中。它们都用在表达式中,连接两个值:一个要在列表中查找的值,以及待查找的列表。这些表达式将求值为布尔值。
mypets=['Zophie','Pooka','fatail']
print('输入一个宠物名:')
name=input()
if name not in mypets:
print('我没有叫'+ name+'的宠物')
else:
print(name+' 是我的宠物。')
#运行结果:
输入一个宠物名:
Pooka
Pooka 是我的宠物。
- 可以在一行代码中,用列表中的值为多个变量赋值,变量的数目和列表的长度必须严格相等,否则会报错。
>>> cat=['fat','black','loud']
>>> size,color,disposition=cat
- 针对+、-、* 、/、和%操作符都有增强的复制操作符,例如spam+=1相当于spam=spam+1。+=操作符也可以完成字符串和列表的连接,*=操作符可以完成字符串和列表的复制。
>>> spam='hello'
>>> spam+=' world'
>>> spam
'hello world'
>>> bacon=['Zophie']
>>> bacon*=3
>>> bacon
['Zophie', 'Zophie', 'Zophie']
3、方法
- 用index()方法在列表中查找值,若该值存在于列表中,就返回他的下标,若不在列表中,就报错。如果列表中存在重复的值,就返回它第一次出现的下标。
>>> spam=['zophie','pookie','fatail','pooka']
>>> spam.index('pooka')
3
>>> spam.index('koine')
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
spam.index('koine')
ValueError: 'koine' is not in list
- 要在列表中添加新值,就使用append()和insert()方法。append()方法将参数添加到列表末尾,insert()方法可在任意下标处插入,它的第一个参数是新值的下标,第二个参数是要插入的新值。
>>> spam=['cat','dog','bat']
>>> spam.append('banana')
>>> spam
['cat', 'dog', 'bat', 'banana']
>>> spam.insert(1,'chicken')
>>> spam
['cat', 'chicken', 'dog', 'bat', 'banana']
方法属于单个数据类型,这两个方法是列表方法,只能在列表上调用,不能在其它值上调用。例如字符串和整型。
>>> eggs='hello'
>>> eggs.append('world')
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
eggs.append('world')
AttributeError: 'str' object has no attribute 'append'
>>> bacon=42
>>> bacon.insert(1,'99')
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
bacon.insert(1,'99')
AttributeError: 'int' object has no attribute 'insert'
- 给remove()方法传入一个值,它将从被调用的列表中删除,若该值在列表中出现多次,只有第一次出现的值会被删除。
>>> spam=['cat','bat','cat','rat','cat']
>>> spam.remove('cat')
>>> spam
['bat', 'cat', 'rat', 'cat']
如果知道想要删除的值在列表中的下标,del语句就很好用,如果知道想要从列表中删除的值,remove()方法就很好用。
- 数值的列表或字符串的列表可以用sort()方法排序,也可以指定reverse关键字参数为True,让sort()按逆序排序。
>>> spam=[2,6,0,-1,-7]
>>> spam.sort()
>>> spam
[-7, -1, 0, 2, 6]
>>> spam=['cat', 'chicken', 'dog', 'bat', 'banana']
>>> spam.sort()
>>> spam
['banana', 'bat', 'cat', 'chicken', 'dog']
>>> spam.sort(reverse=True)
>>> spam
['dog', 'chicken', 'cat', 'bat', 'banana']
注意不能对既有数字又有字符串值的列表排序,sort()对字符串排序时,使用ASCII字符顺序,不是实际的字典顺序,意味着大写字母排在小写字母之前,若需要按普通字典顺序来排序时,就在sort()方法调用时将关键字参数key设置为str.lower。
>>> spam=[2,5,'Alice',9,'bab']
>>> spam.sort()
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
spam.sort()
TypeError: '<' not supported between instances of 'str' and 'int'
>>> spam=['Cat', 'pig', 'dog', 'Zat', 'banana']
>>> spam.sort()
>>> spam
['Cat', 'Zat', 'banana', 'dog', 'pig']
>>> spam=['a','z','A','Z']
>>> spam.sort(key=str.lower)
>>> spam
['a', 'A', 'z', 'Z']
4、续行字符
在行末使用续航字符\,将一条指令写成多行,续行字符之后的一行中,缩进并不重要。
>>> print('four score and seven '+\
'years ago...')
four score and seven years ago...
5、类似列表的类型:字符串和元组
- 字符串和列表实际上很相似,如果将字符串认为是单个文本字符的列表,对列表的很多操作也可以运用到字符串:按下标取值,切片、用于for循环、用于len(),以及用于in和not in操作符。
>>> name='Zophnie'
>>> name[-2]
'i'
>>> name[0:4]
'Zoph'
>>> 'Zo' in name
True
>>> for i in name:
print('***'+i+'***')
***Z***
***o***
***p***
***h***
***n***
***i***
***e***
- 列表和和字符串的重要不同是列表是可变的数据类型,但字符串是不可变的,他不能被修改。改变一个字符串的正确方式是使用切片和连接,构造一个新的字符串,从老的那里复制一部分。
>>> name='Zophine is a cat'
>>> name[7]='the'
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
name[7]='the'
TypeError: 'str' object does not support item assignment
>>> newName=name[0:10]+'the'+name[12:16]
>>> name
'Zophine is a cat'
>>> newName
'Zophine isthe cat'
- 元组是列表数据类型的不可变形式,元组不能让它们的值被修改、添加或删除。元组输入时用()。如果元组中只有一个值,可以在括号内该值的后面加一个逗号,表示这是一个元组,否则python会认为只是在普通括号内输入了一个值。
>>> eggs=('hello',42,0.5)
>>> eggs[1]=99
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
eggs[1]=99
TypeError: 'tuple' object does not support item assignment
>>> type(('hello',))
<class 'tuple'>
>>> type(('hello'))
<class 'str'>
- 函数list()和tuple()将返回传递给它们的值的列表和元组版本。
>>> tuple(['cat','dog',5])
('cat', 'dog', 5)
>>> list(('cat','dog',5))
['cat', 'dog', 5]
>>> list('hello')
['h', 'e', 'l', 'l', 'o']
6、引用
- 将列表赋给一个变量时,实际上是将列表的引用赋给了该变量,引用是一个值,指向某些数据,列表引用是指向一个列表的值。
>>> spam=42
>>> cheese=spam
>>> spam=100
>>> spam
100
>>> cheese
42
>>> ex1=[0,1,2,3,4,5]
>>> ex2=ex1
>>> ex2[1]='hello'
>>> ex1
[0, 'hello', 2, 3, 4, 5]
>>> ex2
[0, 'hello', 2, 3, 4, 5]
在变量必须保存可变数据类型的值时,例如列表和字典,python就保存引用,对于不可变的数据类型的值时,例如字符串、整型或元组,python就保存值本身。
- 当函数被调用时,参数的值被复制给变元,对于列表以及字典,这意味着变元得到的是引用的拷贝。
def eggs(someParameter):
someParameter.append('hello')
spam=[1,2,3]
eggs(spam)
print(spam)
#运行结果:
[1, 2, 3, 'hello']
- 如果函数修改了传入的列表或字典,但不希望这些修改影响到原来的列表或字典,那么python提供了一个copy的模块,其中有两个函数,第一个函数copy.copy()可以用来复制列表或字典这样的可变值,而不是只复制引用。如果要复制的列表中包含了列表,就使用第二个函数copy.deepcopy。
>>> import copy
>>> spam=['A','B','C','D','E']
>>> cheese=copy.copy(spam)
>>> cheese[1]=42
>>> spam
['A', 'B', 'C', 'D', 'E']
>>> cheese
['A', 42, 'C', 'D', 'E']