python
1.第一个python程序
- 交互模式(>>>)退出用exit()
- 打印使用print()函数,打印的内容可以用单引号或者双引号括起来,但是不能够混用
- 命令行模式,可以输入python进入交互模式,也可以通过命令 python hello.py 来运行一个python文件
- 交互模式下查看py文件内容的命令 more hello.py,前提是在对应的文件目录下
- 交互模式下接收输入name=input() 然后通过name可以输出内容
2.python基础
- 注释以#号开头就是注释语句
- 每一行都是一个语句,当语句以冒号:结尾时,缩进的语句为代码块
- 坚持使用四个空格的缩进
- python程序大小写敏感
2.1数据类型和变量
-
整数
-
浮点数 :按照科学记数法表示时,一个浮点数的小数点位置是可变的。如
1.23
,3.14
,-9.01
把10用e替代,1.23x10^9就是1.23e9
-
字符串:
- 字符串是以单引号
'
或双引号"
括起来的任意文本 - 用
r''
表示''
内部的字符串默认不转义 - 字符
\
本身也要转义,所以\\
表示的字符就是\
- 字符串是以单引号
-
布尔值 :布尔值可以用
and
、or
和not
运算 -
常量:通常用全部大写的变量名表示常量
-
变量:
- 在Python中,等号
=
是赋值语句,可以把任意数据类型赋值给变量 - 不用指定数据类型
- 注意作用域的问题
- 在Python中,等号
-
空值
- 用
None
表示。None
不能理解为0
,因为0
是有意义的,而None
是一个特殊的空值
除法:
/
除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:>>> 9 / 3 3.0
还有一种除法是
//
,称为地板除,两个整数的除法仍然是整数:>>> 10 // 3 3
你没有看错,整数的地板除
//
永远是整数,即使除不尽。要做精确的除法,使用/
就可以。因为
//
除法只取结果的整数部分,所以Python还提供一个余数运算,可以得到两个整数相除的余数:>>> 10 % 3 1
- 用
2.2字符编码
编码
- 最早只有127个字符被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为
ASCII
编码 - Unicode把所有语言都统一到一套编码里,这样就不会再有乱码问题了。
- ASCII编码和Unicode编码的区别:ASCII编码是1个字节,而Unicode编码通常是2个字节。
- 如果统一成Unicode编码,乱码问题从此消失了。但是,如果你写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。
- 本着节约的精神,又出现了把Unicode编码转化为“可变长编码”的
UTF-8
编码。 - UTF-8编码把一个Unicode字符根据不同的数字大小编码成1-6个字节,常用的英文字母被编码成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。
- 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
字符串对应函数
-
ord()
函数获取字符的整数表示,chr()
函数把编码转换为对应的字符:>>> ord('A') 65 >>> ord('中') 20013 >>> chr(66) 'B' >>> chr(25991) '文'
-
python的字符串类型是
str
,在内存中以Unicode表示,一个字符对应若干个字节。如果要在网络上传输,或者保存到磁盘上,就需要把str
变为以字节为单位的bytes
。通过==encode()==方法可以编码为指定的bytes
>>> 'ABC'.encode('ascii') b'ABC' >>> '中文'.encode('utf-8') b'\xe4\xb8\xad\xe6\x96\x87'
反过来,如果我们从网络或磁盘上读取了字节流,那么读到的数据就是
bytes
。要把bytes
变为str
,就需要用==decode()==方法:>>> b'ABC'.decode('ascii') 'ABC' >>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8') '中文'
-
python对
bytes
类型的数据用带b
前缀的单引号或双引号表示:x = b'ABC
-
要计算
str
包含多少个字符,可以用len()
函数: -
格式化
在Python中,采用的格式化方式和C语言是一致的,用
%
实现,举例如下:>>> 'Hello, %s' % 'world' 'Hello, world' >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.'
2.3list和tuple
list 方括号
可简单理解为数组
-
list是一种有序的集合,可以随时添加和删除其中的元素。
-
用
len()
函数可以获得list元素的个数>>> len(classmates) 3
-
如果要取最后一个元素,除了计算索引位置外,还可以用
-1
做索引,直接获取最后一个元素:>>> classmates[-1] 'Tracy'
-
list是一个可变的有序表,所以,可以往list中追加元素到末尾 append()方法:
>>> classmates.append('Adam') >>> classmates ['Michael', 'Bob', 'Tracy', 'Adam']
-
要删除list末尾的元素,用==pop()==方法
-
要删除指定位置的元素,用
pop(i)
方法,其中i
是索引位置:>>> classmates.pop(1) 'Jack' >>> classmates ['Michael', 'Bob', 'Tracy']
-
list里面的元素的数据类型也可以不同
-
list元素也可以是另一个list,比如:
tuple 圆括号
-
tuple一旦初始化就不能修改,当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:
>>> t = (1, 2) >>> t (1, 2)
-
没有append(),insert()这样的方法
-
获取元素的方法和list是一样的,你可以正常地使用
classmates[0]
-
最后来看一个“可变的”tuple:
>>> t = ('a', 'b', ['A', 'B']) >>> t[2][0] = 'X' >>> t[2][1] = 'Y' >>> t ('a', 'b', ['X', 'Y'])
其实是list可变
2.4条件判断
age = 3
if age >= 18:
print('your age is', age)
print('adult')
else:
print('your age is', age)
print('teenager')
注意不要少写else了冒号:
。
语句块通过缩进来区分
当然上面的判断是很粗略的,完全可以用elif
做更细致的判断:
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
input
birth = input('birth: ')
if birth < 2000:
print('00前')
else:
print('00后')
以上代码错,因为input返回的数据类型是str
正确写法:
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00后')
2.5 循环
Python的循环有两种:
-
一种是for…in循环
依次把list或tuple中的每个元素迭代出来,看例子:
names = ['Michael', 'Bob', 'Tracy'] for name in names: print(name)
range()
函数可以生成一个整数序列再通过
list()
函数可以转换为list。比如range(5)
生成的序列是从0开始小于5的整数:>>> list(range(5)) [0, 1, 2, 3, 4]
sum = 0 for x in range(101): sum = sum + x print(sum)
-
第二种循环是while循环
n = 1 while n <= 100: if n > 10: # 当n = 11时,条件满足,执行break语句 break # break语句会结束当前循环 print(n) n = n + 1 print('END')
2.6dict和set
dict 大括号
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map
例如:
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95
-
要避免key不存在的错误,有两种办法:
-
一是通过
in
判断key是否存在'Thomas' in d Thomas是key d是dict
-
-
二是通过dict提供的
get()
方法,如果key不存在,可以返回None
,或者自己指定的value:>>> d.get('Thomas') >>> d.get('Thomas', -1) -1
注意:返回
None
的时候Python的交互环境不显示结果。用
pop(key)
方法,对应的value也会从dict中删除:d.pop(‘Bob’)遍历dict:
默认情况下,dict迭代的是key。如果要迭代value,可以用
for value in d.values()
,如果要同时迭代key和value,可以用for k, v in d.items()
set ([])
元素不重复,数学意义上的集合
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集、并集等操作:
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}
重复元素在set中自动被过滤:
>>> s = set([1, 1, 2, 2, 3, 3])
>>> s
{1, 2, 3}
- ==add(key)==方法可以添加元素到set中,可以重复添加,但不会有效果
- ==remove(key)==方法可以删除元素
上面我们讲了,str是不变对象,而list是可变对象。
对于可变对象,比如list,对list进行操作,list内部的内容是会变化的,比如:
>>> a = ['c', 'b', 'a']
>>> a.sort()
>>> a
['a', 'b', 'c']
而对于不可变对象,比如str,对str进行操作呢,a的值是不会发生改变的:
>>> a = 'abc'
>>> a.replace('a', 'A')
'Abc'
>>> a
'abc'
3.函数
3.1函数
- 调用
abs
函数:
>>> abs(100)
100
>>> abs(-20)
20
>>> abs(12.34)
12.34
-
max
函数>>> max(1, 2) 2 >>> max(2, 3, 1, -5) 3
-
Python内置的常用函数还包括数据类型转换函数,比如
int()
函数可以把其他数据类型转换为整数:>>> int('123') 123 >>> int(12.34) 12 >>> float('12.34') 12.34 >>> str(1.23) '1.23' >>> str(100) '100' >>> bool(1) True >>> bool('') False
-
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”:
>>> a = abs # 变量a指向abs函数 >>> a(-1) # 所以也可以通过a调用abs函数 1
3.2定义函数
在Python中,定义一个函数要使用def
语句,依次写出函数名、括号、括号中的参数和冒号:
,然后,在缩进块中编写函数体,函数的返回值用return
语句返回
def my_abs(x):
if x >= 0:
return x
else:
return -x
让我们修改一下my_abs
的定义,对参数类型做检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()
实现:
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type') #抛出异常
if x >= 0:
return x
else:
return -x
返回多个值
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 70.0
但其实这只是一种假象,Python函数返回的仍然是单一值:
>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
(151.96152422706632, 70.0)
原来返回值是一个tuple
3.3函数的参数
位置参数
以往最常使用的参数
默认参数:
完全可以把第二个参数n的默认值设定为2:
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
这样,当我们调用power(5)
时,相当于调用power(5, 2)
:
>>> power(5)
25
例如:
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name)
print('gender:', gender)
print('age:', age)
print('city:', city)
enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')
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()
['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']
可变参数*
计算a^2 + b^2 + c^2 + ……。
由于参数个数不确定,我们首先想到可以把a,b,c……作为一个list或tuple传进来,这样,函数可以定义如下:
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
但是调用的时候,需要先组装出一个list或tuple:
>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84
如果利用可变参数,调用函数的方式可以简化成这样:
>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84
所以,我们把函数的参数改为可变参数:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
有*就代表可变参数
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
>>> nums = [1, 2, 3]
>>> calc(*nums)
14
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple
关键字参数**
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
请看示例:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
#name 和 age是必选参数
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
已经存在dict的调用方法:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, city=extra['city'], job=extra['job'])
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
当然,上面复杂的调用可以用简化的写法:
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
关键字参数中有没有某个关键字的检查
def person(name, age, **kw):
if 'city' in kw:
# 有city参数
pass
if 'job' in kw:
# 有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)
命名关键字参数
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city
和job
作为关键字参数。这种方式定义的函数如下:
def person(name, age, *, city, job):
print(name, age, city, job)
和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
调用方式如下:
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: person() takes 2 positional arguments but 4 were given
比如定义一个函数,包含上述若干种参数:
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)
在函数调用的时候,Python解释器自动按照参数位置和参数名把对应的参数传进去。
>>> 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, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 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': '#'}
>>> args = (1, 2, 3)
>>> kw = {'d': 88, 'x': '#'}
>>> f2(*args, **kw)
a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
3.4递归函数
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
list(range(0)) 的结果为[]