面向过程编程
核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计一条工业流水线,是一种机械式的思维方式
优点:程序结构清晰可以把复杂的问题简单化,流程化
缺点:可扩展性差,一条流线只是用来解决一个问题
应用场景:linux内核,git,httpd,shell脚本
练习:过滤目录下文件内容包含error的文件
grep –rl ‘error’ /dir
使用os模块walk方法:
os.walk会把目录下的二级目录和文件做成一个迭代器,多次使用实现文件路径的拼接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
#grep -rl 'error' /dir/
import
os
def
init(func):
def
wrapper(
*
args,
*
*
kwargs):
g
=
func(
*
args,
*
*
kwargs)
next
(g)
return
g
return
wrapper
#第一阶段:找到所有文件的绝对路径
@init
def
search(target):
while
True
:
filepath
=
yield
g
=
os.walk(filepath)
for
pardir,_,files
in
g:
for
file
in
files:
abspath
=
r
'%s\%s'
%
(pardir,
file
)
target.send(abspath)
#第二阶段:打开文件
@init
def
opener(target):
while
True
:
abspath
=
yield
with
open
(abspath,
'rb'
) as f:
target.send((abspath,f))
#第三阶段:循环读出每一行内容
@init
def
cat(target):
while
True
:
abspath,f
=
yield
#(abspath,f)
for
line
in
f:
res
=
target.send((abspath,line))
if
res:
break
#第四阶段:过滤
@init
def
grep(pattern,target):
tag
=
False
while
True
:
abspath,line
=
yield
tag
tag
=
False
if
pattern
in
line:
target.send(abspath)
tag
=
True
#第五阶段:打印该行属于的文件名
@init
def
printer():
while
True
:
abspath
=
yield
print
(abspath)
g
=
search(opener(cat(grep(
'error'
.encode(
'utf-8'
), printer()))))
g.send(r
'D:\python location\python36\day05\a'
)
|
3、递归
递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身
Python中的递归在进行下一次递归时必须要保存状态,效率低,没有优化手段,所以对递归层级做了限制(其他编程语言中有尾递归方式进行优化)
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
尾递归优化:http://egon09.blog.51cto.com/9161406/1842475
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#直接
def
func():
print
(
'from func'
)
func()
func()
输出:
from
func
from
func
…
from
funcTraceback (most recent call last):
File
"D:/python location/python36/day05/递归.py"
, line
8
,
in
<module>
func()
[Previous line repeated
993
more times]
RecursionError: maximum recursion depth exceeded
while
calling a Python
object
#调用Python对象时的最大递归深度超过了限制
|
如果递归层级过多,会报如上错误
1
2
3
4
5
6
7
8
9
10
11
12
|
#间接
def
foo():
print
(
'from foo'
)
bar()
def
bar():
print
(
'from bar'
)
foo()
foo()
输出:
RecursionError: maximum recursion depth exceeded
while
calling a Python
object
#调用Python对象时的最大递归深度超过了限制
|
修改递归层级限制(默认1000)
1
2
3
4
5
6
|
>>>
import
sys
>>> sys.getrecursionlimit()
1000
>>> sys.setrecursionlimit(
2000
)
>>> sys.getrecursionlimit()
2000
|
练习:
已知:
age(5)=age(4)+2
age(4)=age(3)+2
age(3)=age(2)+2
age(2)=age(1)+2
age(1)=18
首先做判断:
age(n)=age(n-1)+2 #n>1
age(1)=18 #n=1
1
2
3
4
5
6
|
def
age(n):
if
n
=
=
1
:
return
18
return
age(n
-
1
)
+
2
print
(age(
5
))
|
递归的执行分为两个阶段:
1 递推
2 回溯
递归和循环功能差不多,但在不知道循环次数时适合使用递归
练习:
取出列表中所有的元素
1
2
3
4
5
6
7
8
9
10
|
l
=
[
1
,
2
, [
3
, [
4
,
5
,
6
, [
7
,
8
, [
9
,
10
, [
11
,
12
,
13
, [
14
,
15
,[
16
,[
17
,]],
19
]]]]]]]
#
def
search(l):
for
item
in
l:
if
type
(item)
is
list
:
search(item)
else
:
print
(item)
search(l)
|
4、二分法
方法:
判断一个数值是否存在于一个特别大的列表中,如果使用in方法会遍历列表,占内存过多,使用二分法每次会平分列表,占用内存较少
练习:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#二分法
l
=
[
1
,
2
,
5
,
7
,
10
,
31
,
44
,
47
,
56
,
99
,
102
,
130
,
240
]
def
binary_search(l,num):
print
(l)
#[10, 31]
if
len
(l) >
1
:
mid_index
=
len
(l)
/
/
2
#1
if
num > l[mid_index]:
#in the right
l
=
l[mid_index:]
#l=[31]
binary_search(l,num)
elif
num < l[mid_index]:
#in the left
l
=
l[:mid_index]
binary_search(l,num)
else
:
print
(
'find it'
)
else
:
if
l[
0
]
=
=
num:
print
(
'find it'
)
else
:
print
(
'not exist'
)
return
binary_search(l,
32
)
|