一、迭代器
1、迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
1
2
3
4
5
|
l
=
[
'a'
,
'b'
,
'c'
,
'd'
]
count
=
0
while
count <
len
(l):
print
(l[count])
count
+
=
1
|
对于列表可以依赖索引取到值,但是数据结构没有索引,比如字典,就需要一种不依赖索引的取值方式,这就需要迭代器了
2、课迭代对象:凡是对象下有__iter__方法,该对象就是可迭代对象(如字符串,列表,字典,集合,元组,文件等)
迭代器对象:内置有__iter__方法和__next__,得到的结果就是迭代器对象(如文件)
可迭代对象执行__iter__方法变成迭代器对象,执行__next__取到里面的值,每次取一个值
1
2
3
4
5
6
7
8
9
10
11
|
dic
=
{
'name'
:
'wang'
,
'sex'
:
'm'
,
"age"
:
18
}
dic_iter
=
dic.__iter__()
print
(dic_iter.__next__())
#打印取到的name
print
(dic_iter.__next__())
#打印取到的sex
print
(dic_iter.__next__())
#打印取到的age
print
(dic_iter.__next__())
#值取完了,抛出异常StopIteration
while
True
:
try
:
#处理异常的用法
print
(
next
(dic_iter))
except
StopIteration:
break
|
我们通过这种方式取到的值,用for循环就可以简单做到,for循环的原理就是把数据变成迭代器对象执行,并加入处理异常
二、三元表达式和列表推导式
1、三元表达式
1
2
3
|
def
my_max(x,y):
return
x
if
x > y
else
y
#判断语句在中间,左边写执行语句,右边写else语句
print
(my_max(
1
,
3
))
|
2、列表推导式
1
2
3
4
|
l
=
[
'egg%s'
%
i
for
i
in
range
(
10
)]
#列表生成egg0到egg9共十个元素
print
(l)
l
=
[
'egg%s'
%
i
for
i
in
range
(
10
)
if
i >
=
5
]
#加上if判断,只取egg5到egg9共五个元素
print
(l)
|
3、列表推导式的优点
方便,改变了编程习惯,可称之为声明式编程
三、生成器
1、生成器就是迭代器,只要在函数内部出现yield关键字,那么再调用该函数,将不会立即执行函数体代码,会得到一个结果,该结果就是生成器对象
2、yield与return比较
相同点:都有返回值的功能
不同点:return只能返回一次值,而yield可以返回多次值
3、实现range功能
1
2
3
4
5
6
7
8
9
|
def
my_range(start,stop):
while
True
:
if
start
=
=
stop:
raise
StopIteration
yield
start
#碰到yield,程序会暂停,执行next会得到返回值1,接着往下执行start变成2,接着循环,最后取到的值就是1和2
start
+
=
1
g
=
my_range(
1
,
3
)
for
i
in
my_range(
1
,
3
):
print
(i)
|
4、实现 python3 tail.py -f access.log | grep 'error'功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import
time
def
tail(filepath):
with
open
(filepath,
'r'
) as f:
f.seek(
0
,
2
)
while
True
:
line
=
f.readline()
if
line:
#有新的内容,用yield返回,因为yield可以多次返回值
yield
line
else
:
time.sleep(
0.2
)
def
grep(pattern,lines):
for
line
in
lines:
#先查看所有的行,然后找出现error模式的行
if
pattern
in
line:
print
(line,end
=
'')
grep(
'error'
,tail(
'access.log'
))
|
四、面向过程的编程
1、编程思想:核心是过程,即解决问题的步骤,先做什么再做什么,是一种机械式的编程思想
2、优缺点
优点:复杂问题流程化,进而简单化
缺点:可扩展性差
五、递归和二分法
1、递归调用:递归调用是函数嵌套调用的一种特殊形式,函数在调用时,直接或间接调用了自身
递归分为两个阶段:递推,回溯
2、递归的使用:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出
补充:在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
1
2
3
4
5
|
def
salary(n):
if
n
=
=
1
:
return
100
return
salary(n
-
1
)
+
300
print
(salary(
5
))
|
分析:需要salary(5)的值,返回salary(4)+300,接着取salary(4)的值,一直递推,直到遇到结束条件salary(1)返回值为100,然后回溯,得到salary(5)的值1300
3、二分法
将整个列表切分为两份,取中间值和要找的数据作比较,判断在哪一部分,然后再在那一部分切分,再次取值判断,直到最终找到需要的数据
想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模
六、匿名函数
1、lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
2、有名函数与匿名函数的对比
有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能
匿名函数:一次性使用,随时随时定义
应用:max,min,sorted,map,reduce,filter
1
2
3
4
5
6
7
8
9
10
11
|
salaries
=
{
'wang'
:
3000
,
'li'
:
100000
,
'tom'
:
10000
,
'jim'
:
2000
}
print
(
max
(salaries))
#取到的结果是wang
print
(
min
(salaries))
#取到的结果是jim
可以看到结果不是我们想要的,因为
max
,
min
函数只是把字典的key做比较得到的最大值,最小值,而我们要的是后面的工资的最大值和最小值
print
(
max
(salaries.values()))
#取到的结果是100000
print
(
min
(salaries.values()))
#取到的结果是2000
|
3、用zip函数解决(zip函数也叫拉链函数)
1
2
3
4
5
6
7
8
|
a
=
[
1
,
2
,
3
]
b
=
[
'q'
,
'w'
,
's'
,
'e'
]
res
=
zip
(a,b)
print
(
list
(res))
#得到的结果是[(1, 'q'), (2, 'w'), (3, 's')],就是把两个列表的元素一一对应,多余的元素不管
解决上面的问题:把上面字典的键值对调
res
=
zip
(salaries.values(),salaries.keys())
print
(
max
(res))
#得到最大工资的键值对组成的元组(100000, 'li')
print
(
max
(res)[
1
])
#得到工资高的人li
|
4、通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
1
2
|
print
(
max
(salaries,key
=
lambda
k:salaries[k]))
#取到的结果是li,是我们需要的值
print
(
min
(salaries,key
=
lambda
k:salaries[k]))
#取到的结果是jim,是我们需要的值
|
5、按照薪资高低进行排序sorted
1
2
3
4
|
res
=
sorted
(salaries,key
=
lambda
k:salaries[k])
print
(res)
#得到从低到高的顺序['jim', 'wang', 'tom', 'li']
如果要求反向排序,即实现从高到低排序
print
(
sorted
(salaries,key
=
lambda
k:salaries[k],reverse
=
True
))
#得到从低到高的顺序['li', 'tom', 'wang', 'jim']
|
6、map函数,做映射
1
2
3
|
l
=
[
'wang'
,
'li'
]
map
(
lambda
x:x
+
'_man'
,l)
#对列表的每个元素后面添加_man字符串
print
(
list
(
map
(
lambda
x:x
+
'_man'
,l)))
#得到结果['wang_man', 'li_man']
|
7、reduce函数 :实现合并
1
2
|
from
functools
import
reduce
#这个函数需要导入模块
print
(
reduce
(
lambda
x,y:x
+
y,
range
(
1
,
101
)))
#1到100的和,结果是5050
|
8、filter函数,实现过滤
1
2
3
|
l
=
[
'wang_man'
,
'li_man'
,
'tom'
]
res
=
filter
(
lambda
name:name.endswith(
'man'
),l)
#元素里面以字符串man结尾的
print
(
list
(res))
#过滤的结果['wang_man', 'li_man']
|
七、内置函数,要看到结果用print打印出来即可
1、数学运算
1
2
3
4
5
6
7
|
abs
(
-
5
)
# 取绝对值,也就是5
round
(
2.6
)
# 四舍五入取整,也就是3.0
pow
(
2
,
3
)
# 相当于2**3,如果是pow(2, 3, 5),相当于2**3 % 5 结果是3
divmod
(
9
,
2
)
# 返回除法结果和余数,适用于判断数据需要分多少页
max
([
1
,
5
,
2
,
-
2
])
# 求最大值
min
([
9
,
2
,
1
,
3
])
# 求最小值
sum
([
1
,
2
,
3
])
# 求和
|
2、类型转换
1
2
3
4
5
6
7
8
9
|
ord
(
"A"
)
# "A"字符对应的数值
chr
(
65
)
# 数值65对应的字符
bool
(
0
)
# 转换为相应的真假值,在Python中,0相当于False,下列对象都相当于False: [], (), {}, 0, None, 0.0, ''
bin
(
56
)
# 返回一个字符串,表示56的二进制数
hex
(
56
)
# 返回一个字符串,表示56的十六进制数
oct
(
56
)
# 返回一个字符串,表示56的八进制数
list
((
1
,
2
,
3
))
# 转换为列表[1, 2, 3]
tuple
([
2
,
3
,
4
])
# 转换为(2, 3, 4)
dict
(a
=
1
, b
=
"hello"
, c
=
[
1
,
2
,
3
])
# 构建字典{'a': 1, 'b': 'hello', 'c': [1, 2, 3]}
|
3、序列操作
1
2
3
4
|
all
([
True
,
1
,
"hello!"
])
# 所有的元素都相当于True值时返回True
any
(["",
0
,
False
, [],
None
])
# 有任意一个元素相当于True值时返回True
sorted
([
1
,
5
,
3
])
# 序列进行排序,也就是[1,3,5]
reversed
([
1
,
5
,
3
])
# 序列反转,也就是[3,5,1]
|
4、其他常见内置函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
type
([
1
,
2
,
3
])
#[1,2,3]是list类型
len
([
1
,
2
,
3
])
#[1,2,3]的长度是3
range
(
1
,
5
,
2
)
#快速生成序列,1到9,步长为2,结果是1和3
enumerate
函数:
l
=
[
'a'
,
'b'
]
for
i
in
enumerate
(l):
print
(i)
#得到结果是(0, 'a') (1, 'b'),这样可以得到元素对应的索引
eval
函数和
exec
函数
s
=
'1+2+3'
print
(
eval
(s))
#eval用来执行表达式,并返回表达式执行的结果,结果是6
print
(
exec
(s))
#exec用来执行语句,不会返回任何值
print
(
eval
(
'1+2+x'
,{
'x'
:
3
},{
'x'
:
30
}))
#返回33
print
(
exec
(
'1+2+x'
,{
'x'
:
3
},{
'x'
:
30
}))
#返回None
print
(
eval
(
'for i in range(10):print(i)'
))
#语法错误,eval不能执行表达式
print
(
exec
(
'for i in range(10):print(i)'
))
#执行语句,得到语句的结果
|
本文转自 宋鹏超 51CTO博客,原文链接:http://blog.51cto.com/qidian510/2054419,如需转载请自行联系原作者