数据类型变量
整数
浮点数
字符串
布尔值
空值
变量
常量
字符串和编码
list和tuple
list是一个可变的有序表,可以向list中追加元素。
删除list中的元素用pop()方法
tuple是不可变的,和list类似。
tuple的不可变性,在编码中尽量使用tuple代替list
python规定,只有一个元素的tuple定义时必须加一个逗号,
t = (1,)
tuple的不可变只是它的指向不变。例如tuple内嵌list的时候,内嵌list中的元素可变。
判断和循环
if ... elif ... else
for ... in ...
while ...
dict和set
dict的查找速度极快,相当于使用的index查找。
dict中判断一个key是否存在可使用两种方法:
'key' in dict
dict.get('key')或者是指定一个自定义值dict.get('key', false)
删除一个key,使用pop(key)
dict是无序存放的。
dict和list比较的优缺点:查找和插入速度很快,不会随着key的增加而变慢;占用大量内存,内存浪费多。list的查找会随着元素的增多而变慢;占用内存小浪费少。
dict是用空间来换时间。
dict的key必须是不可变对象。
dict根据key来计算value的存储位置,通过key计算位置的算法称为哈希算法,保证hash的正确性,key的对象就不能变。python中,字符串,整数都是不可变,可作为key,list是可变的,不能作为key。
set
set是一组key的集合,不存储value。key不能重复。
创建一个set需要提供一个list作为输入集合
s = set([1,2,3])
重复元素在set中自动被过滤。add(key)添加元素到set,remove(key)删除元素。
set和dict的区别是没有存储对应的value,set的原理和dict一样。同样不可以放入可变对象,
函数
abs()
max()
int()
float()
str()
bool()
函数名就是指向一个函数对象的引用,可以把函数名赋给一个变量:
a = abs
a(-1)
1
定义函数
使用def,依次写出函数名、括号、括号中的参数和冒号 -- 需要确定函数名和参数个数
可以对参数的类型进行检查, 用return返回函数结果。没有返回值的时候自动 返回None,return None
空函数 -- 定义一个函数,使用pass作为该函数的函数体。
参数检查 -- 代码:
1
2
3
4
5
6
7
|
def
my_abs(x):
if
not
isinstance
(x, (
int
,
float
)):
raise
TypeError(
'bad operand type'
)
if
x >
=
0
:
return
x
else
:
return
-
x
|
函数返回多个值,其实在返回多个值的时候返回的是一个tuple,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以python的函数返回多值就是返回一个tuple,写起来更方便。
函数的参数
python除了正常定义的参数外,还可以使用默认参数,可变参数,关键字参数。
位置参数:func(p1,p2) -- p1,p2为位置参数
默认参数:func(p1,p2=value) -- p2=value为默认参数 定义默认参数时,默认参数必须指向不变对象。
可变参数:函数的参数是可变的,可以是0个,1个或多个。
定义可变参数和定义一个list或tuple相比,只是在参数前面加了一个*号。在函数内部,参数接收到的是一个tuple,所以函数代码完全不变。在调用的时候可以传入任意个参数。
1
2
3
4
5
6
|
# 定义一个使用list或tuple作为参数的函数
def
calc(numbers):
sum
=
0
for
n
in
numbers:
sum
=
sum
+
n
*
n
return
sum
|
1
2
3
4
5
|
# 调用的时候需要先弄一个list或tuple
calc([
1
,
2
,
3
])
14
cale((
1
,
2
,
3
))
14
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# 利用可变参数定义一个函数
def
calc(
*
numbers):
sum
=
0
for
n
in
numbers:
sum
=
sum
+
n
*
n
return
sum
# 调用可以是这样的
calc(
1
,
2
,
3
)
14
calc(
1
,
3
,
5
,
7
)
84
|
当一个list或者tuple调用一个可变参数的时候,可以把list或tuple的元素变为可变参数传进去。
1
2
3
|
nums
=
[
1
,
2
,
3
]
calc(
*
nums)
14
|
*nums表示把nums这个list的所有元素作为可变参数传进去。
关键字参数:允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
1
2
|
def
person(name, age,
*
*
kw):
print
(
'name:'
, name,
'age:'
, age,
'other:'
, kw)
|
在调用person函数的时候,name和age必须传之外,接收关键字参数kw(可以传入任意个数的关键字参数)
1
2
3
4
5
|
person(
'bob'
,
35
, city
=
'NewYork'
)
name:bob age:
35
, other:{
'city'
:
'NewYork'
}
person(
'lily'
,
24
, gender
=
'M'
, job
=
'engineer'
)
name:lily age:
24
, other: {
'gender'
:
'm'
,
'job'
:
'engineer'
}
|
关键字参数的作用:扩展函数的功能。
把一个dict作为关键字参数传递给函数。
1
2
3
|
extra
=
{
'city'
:
'beijing'
,
'job'
:
'engineer'
}
person(
'jack'
,
24
,
*
*
extra)
name: jack age:
24
other: {
'city'
:
'beijing'
,
'job'
:
'engineer'
}
|
dict作为关键字参数传递给函数,使用的是值传递,对原dict不影响。
限制关键字参数的名字,使用命名关键字参数。
1
2
3
|
# 只接收city和job作为关键字参数
def
person(name, age,
*
, city, job)
print
(name, age, city, job)
|
命名关键字参数需要一个特殊分隔符*,*后面的参数视为命名关键字参数。*不是参数,缺少*则无法识别位置参数和命名关键字参数。
1
2
3
|
# 调用命名关键字参数
person(
'lucy'
,
22
, city
=
'tokyo'
, job
=
'engineer'
)
lucy
22
tokyo engineer
|
命名关键字参数必须传入参数名,没有将报错。
命名关键字参数可以有默认值。调用带默认值的命名关键字参数可不传入该默认值参数。
参数组合
python定义函数,可用必选参数,默认参数,可变参数,关键字参数,命名关键字参数,除了可变参数不能和命名关键字参数使用外,其他可组合使用。
参数定义的顺序是:必须参数、默认参数、可变参数/命名关键字参数和关键字参数。
1
2
3
4
5
|
def
func(a, b, c
=
0
,
*
args,
*
*
kw):
pass
def
function(a, b, c
=
0
,
*
, d,
*
*
kw):
pass
|
对于任意函数,都可以使用该函数的形式调用,无论它的参数是如何定义的。
1
|
func(
*
args,
*
*
kw)
|
谨记
默认参数一定要用不可变对象
函数的递归
递归的有点是逻辑简单清晰。
递归的时候注意防止栈溢出。函数调用是通过栈实现的,每当进入一个函数调用,栈就会加一层栈帧。函数返回栈就减一层
1
2
3
4
|
def
fact(n):
if
n
=
=
1
:
return
1
return
n
*
fact(n
-
1
)
|
尾递归优化 -- 解决递归调用的栈溢出。尾递归 -- 在函数返回的时候,调用自身并且return语句不能包含表达式,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次都只占用一个栈帧,不会出现栈溢出。
上面的代码改成尾递归:
1
2
3
4
5
6
7
|
def
fact(n):
return
fact_iter(n,
1
)
def
fact_iter(num, product):
if
num
=
=
1
:
return
product
return
fact_iter(num
-
1
, num
*
product)
|
return fact_iter(num-1, num*product)仅返回递归函数本身,num-1和num*product在函数调用前就会被计算,不影响函数调用。
由于python解释器没有做尾递归优化,改成尾递归也会栈溢出。