递归

递归的本质就是函数调用自身,当然也会有一些限制条件,在这里我们思考一个问题,你能递归你自己吗?或者说人能调用自己吗?

暂且不论...

函数自我嵌套

def foo():
print('from foo')
foo() foo() # 进入死循环

你看,这几行代码一执行就陷入了死循环,所以递归肯定需要一个明确的限制条件

调用

直接调用

直接调用就是直接在函数内部调用自身

import sys

# 修改递归层数
sys.setrecursionlimit(10000)
def foo(n):
print('from foo',n)
foo(n+1)
foo(0)

间接调用

间接调指的是不在函数体内调用函数自身,而是通过其他方法间接调用函数自身

def bar():
print('from bar')
foo() def foo():
print('from foo')
bar() bar()

那么递归呢,有两个明确的阶段:

  1. 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
  2. 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯。

递归的精髓在于通过不断地重复逼近一个最终的结果。

'''
...
age(5) = age(4) + 2
age(4) = age(3) + 2
age(3) = age(2) + 2
age(2) = age(1) + 2
age(1) = 26 age(n) = age(n-1) +2
age(1) = 26 # n=1
''' def age(n):
if n == 1:
return 26
res = age(n-1) + 2
return res print(f"age(5): {age(5)}")

age(5):34

为什么要用递归呢

递归的本质就是干重复的活,但是仅仅是普通的重复,我们使用while循环就可以了

lis = [1, [2, [3, [4, [5, [6, ]]]]]]

def tell(lis):
for i in lis:
if type(i) is list:
tell(i)
else:
print(i) # print(f"tell(lis): {tell(lis)}")
tell(lis)

1

2

3

4

5

6

如何使用递归

这里介绍一个二分法的应用

有一个从小到大排列的整型数字列表,我们判断某一个数字是不是在这个列表里面。

from random import randint
nums = [randint(1, 100) for i in range(100)]
nums = sorted(nums)
print(nums)
[1, 2, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 10, 11, 11, 11, 11, 12, 13, 13, 15, 16, 16, 20, 21, 21, 23, 24, 26, 26, 27, 28, 28, 31, 33, 33, 34, 35, 38, 38, 39, 40, 42, 43, 45, 45, 46, 46, 47, 47, 51, 52, 52, 53, 53, 55, 55, 56, 56, 57, 57, 57, 58, 59, 61, 62, 64, 66, 66, 67, 68, 69, 69, 71, 72, 72, 74, 74, 75, 76, 78, 78, 79, 79, 79, 79, 80, 82, 85, 88, 89, 90, 90, 91, 91, 91, 94, 99, 99, 100]
def search(search_num, nums):
mid_index = len(nums)//2
print(nums)
if not nums:
print('not exists')
return
if search_num > nums[mid_index]:
# in the right
nums = nums[mid_index+1:]
search(search_num, nums)
elif search_num < nums[mid_index]:
# in the left
nums = nums[:mid_index]
search(search_num, nums)
else:
print('find it') search(7, nums)

二分法简单来说就是不停地找中值嘛,使用递归来找,不断缩小范围直到找到为止,代码自行去理解哦

内置函数

这里只介绍一部分哈...

掌握

bytes()

解码字符

res = '你好'.encode('utf8')
print(res) ##b'\xe4\xbd\xa0\xe5\xa5\xbd'

chr()/ord()

chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字。

print(chr(65))

##A
print(ord('A')) ##65

divmod()

分栏

print(divmod(10, 3))

##(3, 1)

enumerate()

带有索引的迭代。

l = ['a', 'b', 'c']
for i in enumerate(l):
print(i) ##(0, 'a')
##(1, 'b')
##(2, 'c')

eval()

把字符串翻译成数据类型。

lis = '[1,2,3]'
lis_eval = eval(lis)
print(lis_eval) ##[1, 2, 3]

hash()

是否可哈希。

print(hash(1))

##1

了解

abs()

求绝对值。

print(abs(-13))  # 求绝对值

##13

all()

可迭代对象内元素全为真,则返回真。

print(all([1, 2, 3, 0]))
print(all([])) ##False
##True

any()

可迭代对象中有一元素为真,则为真。

print(any([1, 2, 3, 0]))
print(any([])) ##True
##False

bin()/oct()/hex()

二进制、八进制、十六进制转换。

print(bin(17))
print(oct(17))
print(hex(17)) ##0b10001
##0o21
##0x11

dir()

列举出所有time的功能。

import time
print(dir(time)) ##['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', ##'__package__', '__spec__', 'altzone', 'asctime', 'clock', ##'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', ##'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', ##'strftime', 'strptime', 'struct_time', 'time', 'timezone', ##'tzname', 'tzset']

frozenset()

不可变集合。

s = frozenset({1, 2, 3})
print(s) ##frozenset({1, 2, 3})

globals()/loacals()

查看全局名字;查看局部名字。

# print(globals())
def func():
a = 1
# print(globals())
print(locals()) func() ##{'a': 1}

pow()

print(pow(3, 2, 3))  # (3**2)%3

##0

round()

print(round(3.5))

##4

slice()

lis = ['a', 'b', 'c']
s = slice(1, 4, 1)
print(lis[s]) # print(lis[1:4:1]) ##['b', 'c']

sum()

print(sum(range(100)))

##4950

.import()

通过字符串导入模块。

m = __import__('time')
print(m.time()) ##1556607502.334777

面向对象方法

  1. classmethod
  2. staticmethod
  3. property
  4. delattr
  5. hasattr
  6. getattr
  7. setattr
  8. isinstance()
  9. issubclass()
  10. object()
  11. super()

面向过程编程

面向过程编程是解决问题的一种思想,相当于武林门派,武林门派之间没有好坏之分,因此它与我们之后学习的面向对象编程其实没有好坏之分。

面向过程编程,核心是编程二字,过程指的是解决问题的步骤,即先干什么、后干什么、再干什么、然后干什么……

基于该思想编写程序就好比在设计一条流水线,面向对称编程其实是一种机械式的思维方式。

当我们写登录功能,我们首先需要输入账号、密码,然后认证两次密码是否相同,然后从数据库中读取密码验证用户密码输入是否正确,然后输入验证码……之后,我们就能够实现登录功能。这样把登录功能问题流程化,进而是解决问题的思路非常清晰。

优点:复杂的问题流程化,进而简单化。

注册

1.1 接受用户输入用户名,进行合法性校验,拿到合法的用户名

def check_username():
username = input('username>>>').strip()
if username.isalpha():
return username
else:
print('用户名必须为字母,傻叉')

1.2 接受用户输入密码,进行合法性校验,拿到合法的密码

def check_pwd():
while True:
pwd = input('password>>>').strip()
if len(pwd) < 5:
print('密码长度至少五位')
continue
re_pwd = input('re_password>>>').strip()
if pwd == re_pwd:
return pwd
else:
print('两次输入密码不一致')

1.3 将合法的用户名和密码写入文件

def insert(username, pwd, path='57.txt'):
with open(path, 'a', encoding='utf8') as fa:
fa.write(f'{username}:{pwd}\n')

1.4 注册

def register():
username = check_username()
pwd = check_pwd()
insert(username, pwd)
print(f'{username}注册成功') register()
username>>>nick
password>>>12345
re_password>>>12345
nick注册成功

如果现在我们需要校验用户的年龄,因此我们需要增加一个check_age()方法,并且其他有牵连的地方都需要修改,因此它的扩展性极差。

分层实现功能

生产汽水瓶的流水线,没办法生产特斯拉。流水线下一个阶段的输入与上一个阶段的输出是有关联的。因此他的扩展性极差。

缺点:扩展性差。

  • 用户功能层:实现用户具体的功能。
  • 接口层:连接数据处理层和用户功能层。
  • 数据处理层:处理数据后把结果交给接口层。

分层实现功能的好处:当我们需要实现web端和app端的软件,我们只要把数据处理层和接口层写好,然后实现不同的用户功能层即可,web端使用web端的用户功能层,app端使用app端的用户功能层,但是接口层和数据处理层是通用的。

python-day15(正式学习)的更多相关文章

  1. Python 装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...

  2. Requests:Python HTTP Module学习笔记(一)(转)

    Requests:Python HTTP Module学习笔记(一) 在学习用python写爬虫的时候用到了Requests这个Http网络库,这个库简单好用并且功能强大,完全可以代替python的标 ...

  3. 从Theano到Lasagne:基于Python的深度学习的框架和库

    从Theano到Lasagne:基于Python的深度学习的框架和库 摘要:最近,深度神经网络以“Deep Dreams”形式在网站中如雨后春笋般出现,或是像谷歌研究原创论文中描述的那样:Incept ...

  4. Comprehensive learning path – Data Science in Python深入学习路径-使用python数据中学习

    http://blog.csdn.net/pipisorry/article/details/44245575 关于怎么学习python,并将python用于数据科学.数据分析.机器学习中的一篇非常好 ...

  5. (转载)Python装饰器学习

    转载出处:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方 ...

  6. 正式学习React(五) react-redux源码分析

    磨刀不误砍柴工,咱先把react-redux里的工具函数分析一下: 源码点这里  shallowEqual.js export default function shallowEqual(objA, ...

  7. 正式学习React(一) 开始学习之前必读

    为什么要加这个必读!因为webpack本身是基于node环境的, 里面会涉及很多路径问题,我们可能对paths怎么写!webpack又是怎么找到这些paths的很迷惑. 本文是我已经写完正式学习Rea ...

  8. python网络爬虫学习笔记

    python网络爬虫学习笔记 By 钟桓 9月 4 2014 更新日期:9月 4 2014 文章文件夹 1. 介绍: 2. 从简单语句中開始: 3. 传送数据给server 4. HTTP头-描写叙述 ...

  9. Python装饰器学习

    Python装饰器学习(九步入门)   这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 ? 1 2 3 4 5 6 7 8 # -*- ...

  10. Python的基础学习(第二周)

    模块初始 sys模块 import sys sys.path #打印环境变量 sys.argv#打印该文件路径 #注意:该文件名字不能跟导入模块名字相同 os模块 import os cmd_res ...

随机推荐

  1. Ubuntu:打开JPEG文件错误(Not a JPEG File: starts with 0x52 0x49)

    Ubuntu 16.04.4,造冰箱的大熊猫@cnblogs 2018/7/12 近日下载资料时得到一些后缀为jpg的图片文件.这些图片在手机上能够正常预览,但在Ubuntu的文件管理器中无法预览这些 ...

  2. jQuery_替换操作

    代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title ...

  3. SpringMVC的 transferTo使用

    在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石——SpringMVC其中的一个优势.Spring通过对Servl ...

  4. Spring boot之Hello World访问404

    (1)404 -- 确定地址是否输入正确,,此路径非彼路径 (2)404 -- 是否用对注解,此注解非彼注解 (3)404 -- 包路径是否正确,此包非彼包 (4)404 -- 确认类包是否正确,此类 ...

  5. 桥接模式下,主机能ping通虚拟机,虚拟机ping不通主机

    好像是防火墙阻止了什么东西而导致的无法ping通! 1.打开WIN7防火墙 2.选择高级设置 3.入站规则 4.找到配置文件类型为“公用”的“文件和打印共享(回显请求 – ICMPv4-In)”规则, ...

  6. 20175215 2018-2019-2 第二周java课程学习总结

    一.学生免费申请使用IDEA 下载好IDEA后,设置到最后有一个界面, 我们需要到IDEA官网进行IDEA免费试用权的申请,如果有学校的邮箱,使用学校的邮箱注册并证明是自己的就可以直接通过申请.如下图 ...

  7. TCP定时器 之 TIME_WAIT定时器

    概述 在FIN_WAIT_2收到对端发来的FIN,并回复ACK之后,会进入TIME_WAIT状态,此时添加定时器,定时器超时会将tw控制块从ehash和bhash中删除,并且释放tw控制块: 启动定时 ...

  8. spark MLlib 概念 5: 余弦相似度(Cosine similarity)

    概述: 余弦相似度 是对两个向量相似度的描述,表现为两个向量的夹角的余弦值.当方向相同时(调度为0),余弦值为1,标识强相关:当相互垂直时(在线性代数里,两个维度垂直意味着他们相互独立),余弦值为0, ...

  9. orcal解决锁表

    1.查看历史运行纪录 select * from dba_jobs_running: 2查看锁住的sid和pid select s.sid,s.serial# fromv$session s wher ...

  10. P3956 棋盘

    P3956 棋盘 题解 注释都在代码里了 这道题可以用DFS做,记忆化搜索,维护一个money[ ][ ] 表示到达当前节点的最小花费 不需要记录VIS,因为有一个最小值判断,如果走重复的话一定会得到 ...