---
- 字典:键值对应 类似json
```
d = {'1' : 2, "3": 4}
d["5"] = 6 #插入新的键值
if ('1' in d):#in方法表示判断该键是否在列表中
print("true")
else:
print("flase")
value = d.get('1') #get()方法传入键获取对应的值
print(value)
d.pop("1")#pop()传入键,弹出该对(键-值)
print(d)
```
- 列表
```
list1 = [1, 2, 3, 3]
s1 = set(list1) #去掉重复的元素
list2 = [1, 2, 3, 4, 4]
s2 = set(list2)
print(s1 & s2)#取交集
sorta = [4, 1, 8, 7, 2, 3]
sorta.sort()#对列表中的元素进行排序
sorta.remove(1)#删除列表中为1的元素
```
- 字符串
```
replaceStrA = '1234'
replaceStrB = replaceStrA.replace('1', '55')#将字符串中为1的位置替换为55
print(replaceStrA)
print(replaceStrB)
> 打印结果:
```
![image](1393270E6DB44E2CB322BEF9CFEA01E0)
---
- 函数
```
def get_abs(x):
if x >= 0:
return x
else:
return -x
print(get_abs(-5))
```
```
def nothing():
pass
```
```
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)
print(x,y)
ret = move(100, 100, 60, math.pi / 6)
print(ret)
#函数的返回值个数是可以多个的,形如元组ret = (x,y)
> 打印:
```
![image](6395CFBF016A4A78B487AF58FF2BD3B8)
---
```
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(power(5, 2))
```
```
def build_person(first_name, last_name): # """返回一个字典,其中包含有关一个人的信息"""
person = {'first': first_name, 'last': last_name}
return person
musician = build_person('jimi', 'hendrix')
print(musician)
> 打印:
```
![image](9135A887AB764ED699EAFDB8B9544BBE)
```
def add_end(L=[]):
L.append('END')
return L
list3 = add_end(['1'])
list4 = add_end(['2'])
print(list3)
print(list4)
print(list4)
print(add_end())
print(add_end())
print(add_end())
print(list4)
> 打印:
```
![image](BA780D9BA30D4A868585B26A26362B36)
> https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431752945034eb82ac80a3e64b9bb4929b16eeed1eb9000
![image](B5F11353321343CB97E3CBD4846EB865)
##### 修改上例
- 要修改上面的例子,我们可以用None这个不变对象来实现
```
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
```
##### 现在可以了
---
- 形参传入一个数据结构:列表
```
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc([1, 2, 3]))
```
- 可变参数
1. 定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:
```
#与上例结果一致
def calc1(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calc1(*(1, 2, 3)))
```
2.*nums表示把nums这个list或者元组的所有元素作为可变参数传进去
- 关键字参数
1. 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
```
def person1(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person1('Bob', 35, city='Beijing')
person1('Adam', 45, gender='M', job='Engineer')
extra = {'city': 'Beijing', 'job': 'Engineer'}
person1('Jack', 24, city=extra['city'], job=extra['job'])
person1('Jack', 24, **extra)
> 打印:
```
![image](FED47C28946442ACB4C3DB2657F4BE71)
2.**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra。
- 命名关键字参数
1. 对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查。
仍以person()函数为例,我们希望检查是否有city和job参数:
```
def person(name, age, **kw):
if 'city' in kw:
# 有city参数
pass
if 'job' in kw:
# 有job参数
pass
print('name:', name, 'age:', age, 'other:', kw)
person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)
```
2. 如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
```
def person(name, age, *, city, job):
print(name, age, city, job)
##命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错:
#person('Jack', 24, 'Beijing', 'Engineer') #错误
person('Jack', 24, city='Beijing', job='Engineer')
```
3. 和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
4. 命名关键字参数可以有缺省值,从而简化调用:
```
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
```
5. 如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了
```
def person(name, age, *args, city, job):
print(name, age, args, city, job)
```
- 参数组合
```
def person3(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
person3(*args, **kw)
args = (1, 2, 3)
kw = {'d': 99, 'x': '#'}
person3(*args, **kw)
> 打印:
```
![image](48B0AA3FD8CF44C3A246F463A78E1F48)
- 递归函数
```
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
a = fact(5)
print(a)
```
1. 尾递归,不会爆栈
2. 在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用
3. 栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧
4. 尾递归是指,在函数返回的时候,调用自身本身,并且,return 语句不能包含表达式。
###### (1) 这样,编译器或者解释器就可以把尾递归做优化
###### (2) 使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况
###### (3)相当于内嵌循环
```
def fact_iter1(num, product):
if num == 1:
return product
return fact_iter1(num - 1, num * product)
def fact1(n):
return fact_iter1(n, 1)
a = fact1(5)
print(a)
L = []
n = 1
while n <= 99:
L.append(n)
n = n + 2
```
---
- 切片
```
L = ['Michael', 'Sarah', 'Tracy']
print(L[-2:-1])
L = list(range(10))
print(L[::3])
L = 'ABCDEFG'
print(L[::3])
> 打印:
```
![image](3BE7D7C032AA48EDA5FDA3BB65533D00)
- 迭代
1. 迭代是通过for ... in来完成的
2. dict迭代的是key。如果要迭代value,可以用for value in d.values(),如果要同时迭代key和value,可以用for k, v in d.items()。
3. 判断一个对象是可迭代对象
```
from collections import Iterable
>>> isinstance('abc', Iterable) # str是否可迭代
True
>>> isinstance([1,2,3], Iterable) # list是否可迭代
True
>>> isinstance(123, Iterable) # 整数是否可迭代
False
```
4. 内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:
```
>>> for i, value in enumerate(['A', 'B', 'C']):
... print(i, value)
...
0 A
1 B
2 C
```
- 列表生成式
```
d = [(1, 1), (2, 4), (3, 9)]
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
print([x * x for x in range(1, 11)])
print([x * x for x in range(1, 11) if x % 2 == 0])
print( [m + n for m in 'ABC' for n in 'XYZ'])
> 打印:
```
![image](BE2ECD02E9FB40589AA2E51452CAD1EB)
- 生成器
```
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
```
```
L = [x * x for x in range(10)]
G = [x * x for x in range(10)]
for a in L:
print(a)
for b in G:
print(b)
> 打印
```
![image](7B7CBCBAC7874E61AA2E15EF3288FD8B)
1. 创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。
我们可以直接打印出list的每一个元素,但我们怎么打印出generator的每一个元素呢?
如果要一个一个打印出来,可以通过next()函数获得generator的下一个返回值:
```
print([d for d in 'qwer'])
print([x * x for x in range(10)])
print((x * x for x in range(10)))
g = (x * x for x in range(10))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
for a in g:
print(a)
> 打印:
```
![image](DEB09A9E6BB944E6858066421ADBDAA9)
- 迭代器
1. 直接作用于for循环的数据类型有以下几种:
(1)一类是集合数据类型,如list、tuple、dict、set、str等;
(2)一类是generator,包括生成器和带yield的generator function。
(3)这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。
(4)可以使用isinstance()判断一个对象是否是Iterable对象:
```
from collections import Iterator
print(isinstance((x for x in range(10)), Iterator))
print(isinstance(iter([]), Iterator))
> 打印:
```
![image](04747AD53C3443F293E3D80948ADB31E)
```
#Python的for循环本质上就是通过不断调用next()函数实现的,例如:
for x in [1, 2, 3, 4, 5]:
pass
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
except StopIteration:
# 遇到StopIteration就退出循环
break
```
---
- 函数式编程
```
#类似c语言的函数指针,c++的function仿函数
def add(x, y, f):
return f(x) + f(y)
f = abs
print(f(-1))
print(add(-2, -3, f))
print(abs(-6))
def f(x):
return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(r))
```