python-面向过程
-
关于编码
ASCII & Unicode & UTF-8 文件在内存中使用 Unicode,在硬盘或者需要传输的时候自动转为 UTF-8。Python 中字符串类型是
str
可以使用b''
转为以字节为单位的bytes
,如:x=b’abc’。以 Unicode 表示的str
通过encode()
方法可以编码为指定的bytes
,如’abc’.encode(‘ASCII’) -
关于格式化
输出格式化的字符串,可以与 C 语言一样使用
%
,也可以使用format()
,如’Hi,this is %s’%(‘Jim’),‘Hi,this is {0}’.format(‘Jim’) -
关于数据类型
Python 中内置的数据类型包括数值类型、序列对象和键值对。
- 数值类型
- int 整形
- float 浮点型
- complex 复数
- bool 布尔值
- 序列对象
- str 字符串
- list 列表
- tuple 元组
- 键值对
- set 集合
- dict 字典
字符串使用
[]
定义,其值是可以改变的,也可以使用索引、切边;追加元素到末尾append()
;插入到指定位置insert()
;删除末尾的元素pop()
元组使用
()
定义,其值不可以改变,当只用一个元素时定义为t=(1,)
字典应该
{}
定义,如:t={‘name’:Jim,‘age’=22},可以使用get()
和pop()
set 是一组 key 的集合,不用于储存 value,创建 set 需要提供一个 list 作为输入集合,如 s=set([1,2,3]),可以使用方法
add(key)
,remove(key)
字典与 set 都没有顺序,key 不能重复
- 数值类型
-
关于函数的参数
-
默认参数
1
2
3
4
5
6def power(x,n=2):
s = 1
while n>0:
n = n-1
s = s*x
return s -
可变参数
将参数作为一个元组传入函数内
1
2
3
4
5def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum -
关键字参数
关键字参数允许你传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict,可以用来拓展函数的功能
1
2def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)在使用时可以采用
1
person('Bob', 35, city='Beijing')
1
2extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra) -
命名关键字参数
用于限制关键字参数的名字
1
2def person(name, age, *, city, job):
print(name, age, city, job)如果函数定义中已经有了一个可变参数,后面跟着命名关键字参数就不再需要特殊分隔符
*
,命名关键字参数必须传入参数名。
在组合使用上述函数参数时,顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
-
-
关于迭代
list 和 tuple 可以直接用
for ... in
,而对于 dict 的迭代,由于 dict 没有下标和顺序,对于 key 的迭代使用for key in dict
即可,对于 value 的迭代使用for value in dict.values()
,同时获得 key 和 value 使用for key ,value in dict.items()
为了确定对象是否可以迭代,引入 collections 模块的 Iterable 类型判断:
1
2from collections import Iterable
isinstance('abc', Iterable)为了实现下标循环,使用内置函数 enumerate 可以把一个 list 变成索引-元素对,使用
for i ,value in enumerate(list)
-
关于列表生成式
如果想生成一个 10 以内数的平方值的列表,采用
for...in
1
2
3L = []
for i in range(1,11):
L.append(i*i)若采用列表生成式为
L = [i*i for i in range(1,11)]
关于
for ... in
与if...else...
生成一个偶数列表
[x for x in range(1,11) if x % 2 == 0 ]
生成偶数是原数,奇数为反号的列表
[x if x % 2 == 0 else -x for i in range(1,11)]
在一个列表生成式中,
for
前面的if ... else
是表达式,而for
后面的if
是过滤条件,不能带else
-
关于生成器
生成器是用来避免直接生成一个特别大的列表而只使用前几个元素,造成内存空间的浪费。生成器保存了一种算法,可以生成整个列表,而在使用时可以逐个生成元素,即一边循环一边计算。这种方式既可以获得庞大的数据,又可以节省空间。
生成器的创建有两种方法
- 将列表生成式的
[]
改成()
- 使用 yield 关键字
例如,以列表生成式的方式为
L = [x*x for x in range(1,11)]
,而以生成器的方式为G = (x*x for x in range(1,11))
,而关键字的方式为1
2
3def power(max):
for i in range(1,max+1):
yield i*i生成器的使用方法
- 使用
next()
方法。重复使用,直到捕捉到一个异常 - 使用
for ... in
循环,遍历生成列表
生成器的工作原理
在创建生成器时,列表并不会生成,而在使用
next()
调用时再进行计算生成,并会记录下位置,在下次使用时继续生成。yield
相当于 return 一个值,并会记录下这个位置,再下一次运行时,从 yield 的下一条语句开始执行。当运行到最后时,生成器会抛出一个异常StopIteration
,可以通过处理这个异常,完成列表创建或使用。 - 将列表生成式的
-
关于迭代器
可以直接作用于
for
循环的对象统称为可迭代对象:Iterable
,可以使用isinstance()
判断一个对象是否是Iterable
对象:isinstance([],Iterable)
可以被
next()
函数调用并不断返回下一个值的对象成为迭代器:Iterator
,可以用isinstance()
判断一个对象是否是Iterator
对象:isinstance([],Iterator)
for
循环的本质就是通过不断调用next()
函数实现的 -
关于函数式编程
函数式编程是把函数本身作为参数传入另一个函数,还允许返回一个函数
-
高阶函数
把函数作为参数的函数成为高阶函数,如:
1
2
3f = abs
def add(x,y,f):
return f(x)+f(y)-
map
map()
函数接收两个参数,一个是函数,一个是可迭代的,返回的是一个迭代器,如:1
2
3l = map(abs,[-1,2,-3,4,-5,6,-7,8,-9])
# l是一个迭代器,可通过list()返回一个list
list(l) -
reduce
reduce()
接受一个函数和一个序列,把序列通过函数运算的结果与下一个元素做累计计算,这个函数要求接收两个元素。运行过程为:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
1
2
3def add(x,y):
return x+y
reduce(add,[1,2,3,4,5,6]) -
filter
filter()
用于过滤序列,接收一个函数和一个序列,把函数逐个作用于元素上,返回True
或False
,决定保留还是舍弃该元素(True 返回,False 舍弃)。该函数与map()
一样返回的是一个惰性序列,需要使用list()
计算所有结果。1
2
3
4
5
6# 获得偶数
def is_odd(num):
return num % 2 == 0
num = [0,1,2,3,4,5,6,7,8,9]
list(filter(is_odd,num)) -
sorted
sorted()
是内置的排序函数,同时也是一个高阶函数,可以通过key
来自定义排序,如:1
2
3
4
5
6
7
8
9
10
11
12
13
14# 按绝对值排序
x = [0,-1,3,-5,9,12,-6]
sorted(x,key=abs)
# 忽略大小写排序
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
# 反向排序
sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
# 利用lambda,第一个元素排序
demo = [[1,2,3],[4,5,6],[7,8,9]]
sorted(demo,key=(lambda x:x[0]))
-
-
返回函数
高阶不仅可以接收函数作为参数,也可以返回一个函数1
2
3
4
5
6
7def lazy_sum(*args):
def sum():
ax = 0
for i in args:
ax = ax + i
return ax
return sum当我们调用
lazy_sum()
时,不会立刻求和而是返回了一个 sum 运算,并且 sum 的参数和变量都保存再返回的参数中,称为“闭包”。值得注意的时,闭包中如果使用了局部变量,再多次引用时,局部变量会发生变化 -
匿名函数
匿名函数使用
lambda
关键字,但有个限制就是只能有一个表达式,lambda x : x * x
-
装饰器(待完善)
在代码运行期间动态增加功能的方式,成为“装饰器”
-
偏函数(待完善)
functools.partial
可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单
-
-
位运算
二进制有三种不同的表示形式:原码、反码和补码
反码 补码 正数 原码 原码 复数 符号位不变,其余按位取反 反码+1 Ps:在计算机内部使用补码进行运算,这样减法可以转变为加法
位运算技巧:
-
利用位移计算2的倍数问题
运算 含义 n<<1 n x 2 n>>1 n / 2 n<<m n x 2^m n>>m n / 2^m 1<<n 2^n -
i + (~i) = -1
-
计算n+1与n-1
1
2-~n == n + 1
~-n == n - 1 -
取相反数
取反再+1
1
-n = ~n + 1
-
if(x==a)x=b
或if(x==b)x=a
1
x = a ^ b ^ x
-
判断奇偶性
1
2# 奇数
n & 1 == 1 -
通过
^
交换两个整数1
2
3a^=b
b^=a
b^=b -
最后为1位置的正数
1
a & (-a)
-