主要复习过一遍
简介 略
安装 略
***
第一个Python程序
- 第一行的注释:
# _*_ coding: utf-8 _*_
#!/usr/bin/env python3
- print() 可以接受多个字符串,用逗号隔开,就可以连成一串输出(可以用于不同数据类型的拼接,例如字符串和汉字 ''),但是要注意print会把东都好变成空格。
print("你的卡号是:", int)
input() 例子
input("请输入你的名字:")
***Python基础
- 数据类型和变量
- 缩进(4个空格!不要用tab)
- ‘#’号开头的是注释。
- Python是大小写敏感的!
- 整数,浮点数,字符串(转义,r'',''' '''段落方式),布尔值,空值(None),变量(动态),常量(PI),除法(‘/’取小数除法,// 地板除法,%取余数)
- 字符串和编码
- Unicode通常用2个字节,多的时候会用到4个字节,ASCII只用1个字节,utf-8应运而生。
- utf-8和unicode在浏览和存储的过程中会相互转换。
- Python3的字符床是以Unicode编码的
- 提供了 ord()函数:获取字符的整数表示和chr()函数:把编码转换为对应的字符
- python的str用的是unicode如果在网络或磁盘上需要把str转换为以字节为单位的bytes。
b'str'
这样bytes的每个字符都只占用一个字节。 - str可以通过encode()函数进行编码为指定的bytes
ABC'.encode('ascii')
中文'.encode('utf-8')
纯英文的str可以用ASCII编码为bytes,内容是一样的,含有中文的str可以用UTF-8编码为bytes。含有中文的str无法用ASCII编码,因为中文编码的范围超过了ASCII编码的范围,Python会报错。
- 在bytes中,无法显示为ASCII字符的字节,用\x##显示。
- 如果我们从网络或磁盘上读取了字节流,那么读到的数据就是bytes。要把bytes变为str,就需要用decode()方法:
b'ABC'.decode('ascii')
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
- 如果bytes中只有一小部分无效的字节,可以传入errors='ignore'忽略错误的字节:
b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
中
- 要计算str有多少个字符用 len()函数。
- len()计算的是str的字符数,如果换成bytes则计算字节数。
- 尽量实用utf8 ,别忘了ide也要用utf
- 格式化字符串。现在应该一般用format方式,这里没有先略过,以后补充。
- 用%来实现格式化
Hi, %s, you have $%d.' % ('Michael', 1000000)
- %s表示用字符串替换,%d表示用整数替换,有几个%?占位符,后面就跟几个变量或者值,顺序要对应好。如果只有一个%?,括号可以省略。如果你不太确定应该用什么,%s永远起作用,它会把任何数据类型转换为字符串.
- 格式化整数和浮点数还可以指定是否补0和整数与小数的位数:
print('%2d-%02d' % (3, 1))
print('%.2f' % 3.1415926)
- 有些时候,字符串里面的%是一个普通字符怎么办?这个时候就需要转义,用%%来表示一个%:
growth rate: %d %%' % 7
- format() 传入的参数依次替换字符串内的占位符{0}、{1}等:
Hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.125)
19.课后作业,计算百分比的方式是 (s2-s1)/s1*100
- 使用list和tuple
- list是一种有序的集合,何以随时添加和删除其中的元素.
- list_name = [1, 2, 3,4]
- 用len()可以获得list有多少个元素.
调取元素用list名和索引
list_name[0]
- 当索引超出范围会报错'IndexError'如果想确保部越界,最后一个元素的所以可以是len(list_name)-1
- 也可以用 -1 做索引.
- 追加元素用
list_name.append('jack')
- 把元素插入到指定位置
list_name.insert(1, 'jack')
- 删除末尾的元素,会返回删除的值.
list_name.pop()
- 删除指定位置的元素用pop(i)
list_name.pop(1)
- 要把某个元素替换成别的元素可以直接赋值给索引位置.
list_name[1] = 'shark'
- list里面可以存储不同的数据类型,甚至是另一个list(嵌套list)
13.访问list中的list中的值用两个索引list_name[1][2]
- list中可以一个元素都没有就是空list,len()是0,创建一个空list
list_name = []
- tuple元组,初始化后不能更改.没有append,insert等方法.获取同list.
- 不可变代表更安全.能用tuple代替list的时候就尽量代替它.
- 空tuple
t = ()
- 如果定义只有一个元素的tuple需要写为
t = (1, )
19.可变的tuple,可以在tuple中嵌套一个list.这样就可以更改list中的内容了.
- 条件判断
- if
age = 20
if age >= 18:
print('...')
- else:
age = 3
if age >= 18:
print('your age is', age)
print('adult')
else:
print('your age is', age)
print('teenager')'
- elif
age = 3
if age >= 18:
print('adult')
elif age >= 6:
print('teenager')
else:
print('kid')
- if语句是从上往下判断的 如果某个判断是True,那么就是执行相应的语句把后面的语句忽略掉.
- if条件判断可以简写,默认为True就执行.
if x:
print('True')
- int()函数可以将str中的数字变为数字类型.
- 循环
- for in 句式.
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
- 求和例子
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
- range()函数生成数字用的,参数是起始和结束的数,应该是左区间.
- 然后可以用list()函数直接将range()函数生成的出来的数字转换成为list
- while循环.只要条件满足就一直循环,条件不满足就退出循环.
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
- break 可以提前退出循环.
```n = 1
while n <= 100:
if n > 10: # 当n = 11时,条件满足,执行break语句
break # break语句会结束当前循环
print(n)
n = n + 1
print('END')
48. continue 跳过但德国前循环直接开始下一个循环.
n = 0
while n < 10:
n = n + 1
if n % 2 == 0: # 如果n是偶数,执行continue语句
continue # continue语句会直接继续下一轮循环,后续的print()语句不会执行
print(n)
49. 不要滥用break和continue语句。break和continue会造成代码执行逻辑分叉过多,容易出错。大多数循环并不需要用到break和continue语句,上面的两个例子,都可以通过改写循环条件或者修改循环逻辑,去掉break和continue语句。
- dict和set
50. 词典dict.用键和值来配对存储,查找速度快.
51. 例子
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Michael']
95
3.list省内存,数据多了以后查找慢,dict费内存查找快.
52. 要在词典中加入内容`d['key'] = value`
53. 由于一个key只能对应一个value,所以如果多对一个key操作value会被覆盖掉.
54. 如果取key不存在的内容时会报错.KeyError
55. 可以通过in方法判断key是否存在
'Thomas' in d
False
56. 通过get()方法,如果key不在就会返回None或者自己指定的value
d.get('Thomas')
d.get('Thomas', -1)
-1
57. 要删除一个key用pop(key)的方法,相关的value会直接被删除.
58. 注意 dict只通过key来操作是没有顺序的哦!
59. list和dict的特点(复制)
>查找和插入的速度极快,不会随着key的增加而变慢;
需要占用大量的内存,内存浪费多。
而list相反:
查找和插入的时间随着元素的增加而增加;
占用空间小,浪费内存很少。
所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。
这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。
要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key:
key = [1, 2, 3]
d[key] = 'a list'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list
60. set 和dict类似也是一组key的集合,但是不存储value,由于key不能重复所以在set中没有重复的key.
61. 传入的重复的东西会被自动过滤掉.
62. 通过add(key)的方式可以添加元素到set中(重复添加不会有效果的)
63. remove(key)可以删除相关key
64. 其实就是数学的集合,没有重复的
65. 两个集合可以做运算 会去重.
s1 = set([1, 2, 3])
s1 = set([1, 2, 3])
s1 & s2
{2, 3}
s1 | s2
{1, 2, 3, 4}
***
# 函数
- 调用函数
1. Python内置了很多的函数,可以直接调用可以直接看官网有那些函数[Python函数官网](http://docs.python.org/3/library/functions.html#abs)
也可以在交互界面用help()函数来查看。
2. 调用函数时要传入参数,如果传入的参数数量不对会报`TypeError`的错误,并且会告诉你具体内容。
3. 如果参数数量对,但是类型不对,也不会接受也会报`TpyeError`的错误。
4. 数据类型转换函数比如int(),float(),str(),bool()
5. 函数名字的本身其实就是只想一个函数对象的引用,所以也可以把函数命名为其他名字。
6. hex()函数用来把数字转换成十六进制表示的字符串(返回的是字符串哦)。
- 定义函数
1. 用def语句定义函数,依次写函数名,括号,括号中的参数和冒号,然后在缩进的块中编写函数体。例子:
def my_abs(x):
if x >=0:
return x
else:
return -x
2. 这里注意,函数体内部在执行到`return`的时候,函数就执行完毕了并且将结果返回。因此函数内部通过条件判断和循环可以实现非常复杂的逻辑。
3. 如果没有return语句,函数执行完毕后也会返回结果,知识结果为`None`。`return None`可以简写为`return`。
4. 可以将函数保存为py文件,在后期直接用import导入即可使用,这里要注意需要在相关的目录下。
5. 空函数,可以定义一个函数 函数主题写一个pass 用来占位。
6. 参数检查 用 isinstance()函数,暂略 后面专门学习。
7. 函数返回多个值 `return x,y`这里其实返回的仍然是一个值只是返回的是tuple而已,措意可以带出来两个数。
- 函数的参数
1. 位置参数。
def power(x):
return x * x
这里对于power(x)函数,参数x就是一个位置参数,当调用power函数时,必须传入有,且仅有的一个参数。
2. 现在要计算各种次方怎么办? 如下 x表数字,n表次方,这两个参数仍然是默认参数
```
def power(x, n)
s = 1
while n > 0 :
n = n - 1
s = s * x
retun s
```
3. 默认参数,如果位置参数有两个我们只给一个参数就会报错,如果在位置参数次方上加入`n = 2` 就会默认算2次方,这样只给x参数就可以了,如果想要计算其他次方 在带入n的参数。
一般把变化大的参数放在前面,变化小的参数放在后面。这样一般就可以把变化小的参数设置为默认参数了
4. 默认参数在有多个的时候,可以跳过有默认参数的参数,直接写后面的参数名 = 多少。
5. 默认参数必须指向不变对象!
6. 可变参数。参数可以是任意个 也可以是0个。例子:
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
这样调用calc函数的时候就可以组装先组装出一个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就是在参数的前面家 `*`号,就可以在调用的时候放入任意参数了。
calc(1, 2)
5
calc()
0
0个参数也是可以的。
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。
7. 关键字参数 关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。例子:
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)8. 在函数person中除了必选的name和age参数外,还接受关机自参数kw 在调用时可以只传入必选参数,也可以传入任意个关键字参数。例子:
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'}
```
他的作用是可以扩展功能,在保证可以接受到name和age这两个参数的前提下,可以接受到更多的命令。
- 和可变参数类似可以先组装一个dict然后把dict作为关键字参数传入进去
>>> extra = {'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。
- 命名关键字参数。如果想要限制关机自参数的名字,例如,只接收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
由于调用时缺少参数名city和job,Python解释器把这4个参数均视为位置参数,但person()函数仅接受2个位置参数。
- 名关键字参数可以有缺省值,从而简化调用:
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
这样就可以不传入city参数了
- 使用命名关键字参数时,要特别注意,如果没有可变参数,就必须加一个作为特殊分隔符。如果缺少,Python解释器将无法识别位置参数和命名关键字参数:
- 组合参数。在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
- 比如定义一个函数,包含上述若干种参数:
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': '#'}
- 所以,对于任意函数,都可以通过类似func(*args, **kw)的形式调用它,无论它的参数是如何定义的。
- 虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。
- Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。
默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:
*args是可变参数,args接收的是一个tuple;
**kw是关键字参数,kw接收的是一个dict。
以及调用函数时如何传入可变参数和关键字参数的语法:
可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({'a': 1, 'b': 2})。
使用*args和**kw是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符*,否则定义的将是位置参数。
- 递归函数。
- 函数的内部可以调用其他函数,但是如果可以调用自身,那么就是递归函数。
- 暂略
高级特性
- 切片