递归
递归:递归是函数调用函数本身,然后有结束条件
递归的核心: 递进的时候能够达到一个结果,问题规模越来越小(不一定要真正的达到); 设置一个条件,能够让最后一次函数调用结束;
递归代码(递归更多的是一种思想,用来解决某种问题)
count = 1 # 2 # 3
def f1():
global count # 下面的count是全局的count
if count > 100:
return
count += 1 # 2 # 3
print(count) # 2 # 3
f1()
f1()
变量提升:在调用函数阶段,def里的代码是一起读取再逐行运行的
'''
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。 #
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: True
'''
s = '{[]}'
def isValid(s: str) -> bool:
print(s)
# s = ''
if not s: # 判断s是否为空
return True
if s.find('[]') != -1 or s.find('{}') != -1 or s.find('()') != -1: # 证明s里面有 ()/[]/{}
if '{}' in s:
s = s.replace('{}', '')
if '[]' in s:
s = s.replace('[]', '')
if '()' in s:
s = s.replace('()', '')
if s == '': # s = '[]'
return True
res = isValid(s)
print('res:',res)
if not res:
return False
else:
return False
return True
res = isValid(s)
print(res)
def isValid(s):
if '{}' in s:
s = s.replace('{}','')
if '[]' in s:
s = s.replace('[]','')
if '()' in s:
s = s.replace('()','')
if '{}' in s or '[]' in s or '()' in s:
isValid(s)
elif s == '':
print('True')
return True
else:
print('False')
return False
isValid("()[[]]")
求年龄
我知道第一个人的年龄16,我要求出5个人后的年龄-->26
age = 16
def age_func(x):
global age
if x == 0:
return age
return age_func(x - 1) + 2
res = age_func(5)
print(res) # 26
'''
age_func(5) --> return age_func(4)+2 == 24+2 =26
age_func(4) --> return age_func(3)+2 == 22+2 = 24
age_func(3) --> return age_func(2)+2 == 20+2 = 22
age_func(2) --> return age_func(1)+2 == 18+2 = 20
age_func(1) --> return age_func(0)+2 == 16+2= 18
'''
汉诺塔问题
'''
汉诺塔问题不管在任何编程语言里都是经典问题,是采用递归算法的经典案例,该问题可以抽象如下:
一 3根圆柱A,B,C,其中A上面串了n个圆盘
二 这些圆盘从上到下是按从小到大顺序排列的,**大的圆盘任何时刻不得位于小的圆盘上面**
三 **每次移动一个圆盘**,最终实现将所有圆盘移动到C上
利用Python语言接近自然语言的特性,开发者可以更容易的将递归算法翻译成程序语句,需要的代码量很小。汉诺塔问题的解决步骤用语言描述很简单,仅三步:
A,B,C三个圆柱,分别为初始位,过渡位,目标位,设A柱为初始位,C位为最终目标位
(1)将最上面的n-1个圆盘从初始位移动到过渡位
(2)将初始位的最底下的一个圆盘移动到目标位
(3)将过渡位的n-1个圆盘移动到目标位
对于递归算法中的嵌套函数f(n-1)来说,其初始位,过渡位,目标位发生了变化
'''
def move(n, a, b, c): # n为圆盘数,a代表初始位圆柱,b代表过渡位圆柱,c代表目标位圆柱
if n == 1:
print(a, '-->', c)
else:
move(n - 1, a, c, b) # 将初始位的n-1个圆盘移动到过渡位,此时初始位为a,上一级函数的过渡位b即为本级的目标位,上级的目标位c为本级的过渡位
print(a, '-->', c)
move(n - 1, b, a, c) # 将过渡位的n-1个圆盘移动到目标位,此时初始位为b,上一级函数的目标位c即为本级的目标位,上级的初始位a为本级的过渡位
move(2, 'A', 'B', 'C')
'''
A --> B
A --> C
B --> C
'''
# n层看成两层,1个为1层,余下的n-1层排序好了
# n-1层看成2层,1个为1层,余下的n-2层排序好了
# 5层看成2层,1个为1层,余下的4层排序好了
# 4层看成2层,1个为1层,余下的3层排序好了
# 3层看成2层,1个为1层,余下的2层排序好了
# 2层看成1层,1个为1层,余下的1层排序好了
# 1层 A-->C
内置函数
# 掌握
print(abs(-10)) #绝对值
print(bin(97)) #二进制
print(hex(97)) #十六进制
print(oct(97)) #八进制
print(hash(1)) #是否可哈希
print('callable(func):', callable(func)) # 是否能够调用
print('callable([1,]):', callable([1, ]))
print('chr(97):', chr(97)) #参考ascii码返回十进制对应字母
print(ord('a')) #参考ascii码返回字母对应十进制数字
for ind, value in enumerate([1, 2, 3]):
print(ind, value)
print("eval('1+1'):", eval('1+1')) #去掉括号内引号
exec('print("1234234234")') # 执行括号内部代码
# 了解
print(all([1, 2, 3])) # 如果列表内所有元素的bool值都为真则为真
print(any([1, 2, 3])) # 如果列表内只要有一个元素的bool值为真则为真
print(ascii([1, 234])) # 如果为ascii编码则直接返回,否则转二进制
print(bytearray([1, 2, 3])) # 转二进制
print(bytes([1, 2, 3])) # 转二进制
# import time
# print(dir(time)) #返回模块中所有内置方法
print(divmod(10, 3)) #返回取整数和余数
s = frozenset({'skdfjklsdjf', 'sdkfjlk', 'aaaaaa'})
print(id(s))
name = 'nick'
print('globals():', globals()) # 返回所有全局变量
print(hash('234234234')) # 无论你放入什么字符串,永远返回一个固定长度的随机字符串
print(help())
def func():
print('locals():', locals()) #返回当前所有变量
func()
print(pow(2, 3)) #幂运算
print(round(3.55)) #四舍五入
s = slice(0,2,1) #切片
lis = [1,1,23]
print(lis[s]) # lis[0:2:1]
print(sum([1,2,23]))
time = __import__('time') # 导入模块的另外一种方式
print(time.time())
# 记住,只要记住一个enumerate()
面向过程编程
面向过程编程:流水线的思想
优点:
1. 思路清晰
缺点:
1. 上一个过程完蛋了,下一个过程也完蛋
2. 功能与功能之间不独立
3. 牵一发而动全身,不方便修改/扩展功能,可扩展性差