在Python中,变量是没有数据类型的,是动态可变的。比如、
1
2
3
4
5
62 x=
x
2
'hahaha' x=
x
'hahaha'
标识符的命名规则:
- 以数字,字母,下划线组成,且不能以数字开头
严格区分大小写
- 不能使用关键字,如if、try等命名
命名规范
- 在Python里的变量、函数名和模块名使用下划线连接;
- 类名使用大驼峰法命名(如MyName)
print()
1
2
3
4
5"hello","world","hi")#默认空格隔开 print(
hello world hi
"hello","world","hi",sep='+')#seq是分隔符参数 print(
hello+world+hi两个print之间默认会换行(end默认是
'\n'
),可以使用end参数改1
2
3
4print("hello","world","hi",sep='+',end="~~~~~~~")
print("你好")
hello+world+hi~~~~~~~你好 #改成了用~~~~~~~~分隔,而不是换行input()
不管用户输入的是什么,input()接收/保存的都是字符串类型
Python中的进制
默认print()是10进制,以
0b
开头的是二进制,0o
开头是八进制,0x
是16进制1
2
3
4
5
6a=98#10进制
b=0b101101101#2进制
c=0o34#8进制
d=0x23#16进制
print(a,b,c,d)#默认转化为10进制输出1
98 365 28 35
进制转换
1
2a=98#10进制
print(bin(a),oct(a),hex(a))#分别把a转换为2,8,10进制1
0b1100010 0o142 0x62
数据类型转换
字符串->整数:
int()
1
2
3
4
5
6a='31'
b=int(a)
print(a,b)
print(type(a),type(b))1
231 31
<class 'str'> <class 'int'>
注意:若某字符串,如`hello`不是合法数字,则转换时会报错
也可以指定字符串转换为数字的进制,如下例
1
2
3
x='1a2c'
y=int(x,16)#将字符串转换为16进制的数字
print(y)#以10进制方式输出
1
6700
str->float:
float
1
2
3a='12.34'
b=float(a)
print(b) #输出:12.34其他->字符串:
str()
使用bool内置类可以将其他数据类型转换为布尔值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21100)) print(bool(
True
-1)) print(bool(
True
0)) print(bool(
False
'hello')) print(bool(
True
'False')) print(bool(
True
''))#只有空字符串可以转为False布尔型 print(bool(
False
None)) print(bool(
False
#空list print(bool([]))
False
#空tuple print(bool(()))
False
#空集合 s=set()
bool(s)
False
字符串支持有限的加法和乘法运算
+
:拼接两个字符串*
:如hello*3
则打印3次hello
元组的括号有时可以省略
1
2
3'a','b','c' x=
x
('a', 'b', 'c')加*表示可变长度
1
2
3
4
5
6
7
81,2,3,4#报错了 o,p,q=
Traceback (most recent call last):
File "<pyshell#75>", line 1, in <module>
o,p,q=1,2,3,4
ValueError: too many values to unpack (expected 3)
1,2,3,4 o,*p,q=
print(o,p,q)
1 [2, 3] 4数字和字符串之间,做==运算的结果是False,做!=是True。除此之外,不支持其他比较运算
短路问题
1
2
3#ex1
4>3 and print('hello world')
4<3 and print('你好世界')#第一个条件不满足,短路1
hello world
1
2
3#ex2
4>3 or print('唉')#第一个条件满足,短路
4<3 or print('哼')1
哼
逻辑与运算做取值时,取第一个为False的值;如果所有运算数都是True,则取最后一个值
逻辑或运算做取值时,取第一个为True的值;如果所有运算数都是False,则取最后一个值
位运算
与、或、异或
左移、右移
1
2
3
4
5
65 x=
3)#a<<n ==>a*2的n次方 print(x<<
40
15 y=
2)#a>>n ==>a除以2的n次方 print(y>>
3
pass
关键字没意义,只是用来占位的
3元表达式对if…else进行转化
1
2
3
4
520 num1=
30 num2=
if num1>num2 else num2 x=num1
x
30打印图案
1
2
3
4
5
6
7
8
9
10
11#方法1:刚刚从隔壁C语言转过来,看这个比较舒服
for i in range(1,6):
for j in range(i):
if j<i-1:
print('*',end='')
else:
print('*',end='\n')
#方法2:不得不说,Python大法好
for i in range(1,6):
print(i*'*') #别忘了print()默认的end参数是换行1
2
3
4
5
6
7
8
9
10*
**
***
****
*****
*
**
***
****
*****打印99乘法表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22for i in range(1,10):
for j in range(1,i+1):
print(j,'*',i,'=',j*i,end=' ')
print('\n')
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81emm,有点丑,改一下
sep
参数即可(seq默认是空格)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21for i in range(1,10):
for j in range(1,i+1):
print(j,'*',i,'=',j*i,sep='',end=' ')
print('\n')
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
但还是丑,再改一下end
参数
1 | for i in range(1,10): |
for …else
当循环里的break没有被执行的时候,就会执行else语句
1
2
3
4
5
6for i in range(101,201):
for j in range(2,i):
if i%j==0:
break;#不是素数
else:
print(i,'是素数')range()内必须是整数
字符串
可以用一对三个单/双引号、一堆单/双引号 来表示字符串
\
表示转义字符在字符串前面加上
r
表示原生字符很灵活!
可迭代对象:str,list,tuple,dict,set,range
,都可以遍历
注意:字符串是不可变数据类型
切片语法:str[start:end:step],左闭右开
step不能为0
可以倒序,when step<0,但此时start应该大于end
str[::]代表全部复制
str[::-1]代表倒序复制全部
str中常用的查找方法
find
index
rfind
rindex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24'abcde' s=
>>> s.find('b')
1
>>> s.index('b')
1
>>> s.find('asd') #找不到返回-1
-1
>>> s.index('sdfg') #找不到会报错
Traceback (most recent call last):
File "<pyshell#272>", line 1, in <module>
s.index('sdfg')
ValueError: substring not found
>>> s='aabcdefe'
>>> s.rfind('a')
>>> 1
>>> s.rindex('a')
>>> 1
>>> s.rfind('asdf')
>>> -1
>>> s.rindex('asdf')
>>> Traceback (most recent call last):
>>> File "<pyshell#282>", line 1, in <module>
>>> s.rindex('asdf')
>>> ValueError: substring not found
is开头的方法是判断方法,返回布尔值
replace
1
2
3
4'hello' word=
'l','x')#将字母‘l’替换为字母‘x’ m=word.replace(
m
'hexxo'split rsplit splitlines partition rpartition
1
2
3
4
5
6'a-b-c-d' x=
'-') y=x.split(
#字符串是不可变数据类型 x
'a-b-c-d'
y
['a', 'b', 'c', 'd']1
2
3
4
5
6
7'a-b-c-d' x=
'-',2)#分割两次(分成3部分) z=x.split(
z
['a', 'b', 'c-d']
'-',2)#rsplit就是从后面开始分割 zz=x.rsplit(
zz
['a-b', 'c', 'd']partition可以指定一个字符作为分隔符,分为
3
部分rpatition就是从后面开始找
比如分割文件名和后缀名
1
2
3
4
5'2020.05.21.mp4' x=
'.') x.partition(
('2020', '.', '05.21.mp4')
'.') x.rpartition(
('2020.05.21', '.', 'mp4') #分割文件名和后缀名修改大小写
1
2
3
4
5
6
7
8
9
10
11
12
13
14'hello word HAHA mie' x=
#capitalize:只让首字母大写
x.capitalize()
'Hello word haha mie'
#upper:全大写
x.upper()
'HELLO WORD HAHA MIE'
#lower:全小写
x.lower()
'hello word haha mie'
#title:每个单词的首字母大写
x.title()
'Hello Word Haha Mie'ljust(width,fillchar)
让字符串以指定长度width显示,如果长度不够,默认在右边使用空格补齐,可用fillchar参数修改。
同理
rjust(width,fillchar)
是在另一侧进行center(width,fillchar)
是在中间进行1
2
3
4
5
6
7
8
9
10
11'Monday' x=
10,'+') x.ljust(
'Monday++++'
10,'+') x.rjust(
'++++Monday'
10,'*') x.center(
'**Monday**'
11,'*') x.center(
'***Monday**'
12,'*') x.center(
'***Monday***'去空格(strip()默认删除空格)
1
2
3
4
5
6
7' apple ' x=
x.lstrip()
'apple '
x.rstrip()
' apple'
x.strip()
'apple'也可以指定要删除的内容
1
2
3
4
5
6
7
8
9'*** apple****' x=
'*') x.lstrip(
' apple****'
'*') x.rstrip(
'*** apple'
x.strip()
'*** apple****'
'*') x.strip(
' apple'
列表 ==> 字符串:
join()
1
2
3
4
5'a','b','c','d'] lis=[
'-'.join(lis)
'a-b-c-d'
'*'.join('hello')#join后面是可迭代对象
'h*e*l*l*o'字符编码查看
1
2
3
4
5'h*e*l*l*o'
'a') ord(
97
65) chr(
'A'使用encode方法,可以将字符串转换为对应的编码集结果
用decode方法可以解码
in 和 not in
1
2
3'word' x=
if 'x' in x:
print("存在")
格式化输出print(),与C语言类似
1
2
3
4name='fhs'
age=12
f=3.1415926
print('大家好,我叫%s,我%d岁了,我喜欢的浮点数是%f'%(name ,age,f))1
大家好,我叫fhs,我12岁了,我喜欢的浮点数是3.141593
在%s前面再加一个%,类似转义字符的功能
1
2"我叫%%s,我%d 岁了"%12) print(
我叫%s,我12 岁了format
{}内什么也不写,自动一一对应
1
2
3
4name='fhs'
city='sd'
age=12
print("你好,我叫{},来自{},今年{}岁了".format(name,city,age))1
你好,我叫fhs,来自sd,今年12岁了
{}写下标,按照下标从小到大一一对应
1
2
3
4name='fhs'
city='sd'
age=12
print("你好,我叫{1},来自{0},今年{2}岁了".format(city,name,age))1
你好,我叫fhs,来自sd,今年12岁了
{}内指定变量名字
1
2
3
4name='fhs'
city='sd'
age=12
print("你好,我叫{name},来自{city},今年{age}岁了".format(city='sd',name='fhs',age=12))1
你好,我叫fhs,来自sd,今年12岁了
{下标}和{变量}可混合使用,但顺序有要求
1
2
3
age=12
print("你好,我叫{1},来自{0},今年{age}岁了".format('sd','fhs',age=12))
1 | 你好,我叫fhs,来自sd,今年12岁了 |
还可以用列表,字典等传入
1
2
3
4
5
6
7
8
9
10
d=['fhs',12,'sd',179]
b='我是{},我{}岁了,来自{},身高{}'.format(d[0],d[1],d[2],d[3])
bb='我是{},我{}岁了,来自{},身高{}'.format(*d) #更快的写法
info={'name':'hhh','age':10001,'addr':'sdd','height':1111}
bbb='我是{name},我{age}岁了,来自{addr},身高{height}'.format(**info)#列表加一个*,字典加两个*
print(b)
print(bb)
print(bbb)
1
2
3
我是fhs,我12岁了,来自sd,身高179
我是fhs,我12岁了,来自sd,身高179
我是hhh,我10001岁了,来自sdd,身高1111
list
可变数据类型
添加元素:
- append()
- insert(index,object)
- extend():
A.extend(B)
删除元素
- pop(index): 删除一个元素,默认删除最后一个位置(index=-1)的元素,可用index参数修改默认值
- remove() :删除指定元素,不存在会报错,若存在多个,则删除下标最小的那个
- clear() :清空list
- del :不推荐
查询
- count(‘str_name’):计数
- index(‘str_name’): 返回str_name在列表中的下标
排序
sort(reverse=True/False) ,会改变原始列表(也就是对原始列表进行排序)
1
2
3
4
5
6
7
8
92,3,1,5,4,6,7,9,8] num=[
num.sort()
num
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2,3,1,5,4,6,7,9,8] num=[
True) num.sort(reverse=
num
[9, 8, 7, 6, 5, 4, 3, 2, 1]sorted()是内置函数,不会改变原始list,而会生成一个新的list
reverse()用于将list翻转,等价于`list[::-1]`
1
2
3
4
5
lis
['a', 'b', 'c', 1, 2]
lis.reverse()
lis
[2, 1, 'c', 'b', 'a']
不可变类型:尝试修改时会产生一个新的变量,也就是指向了新的地址
- 数字
- 字符串
- 元组
可变类型:修改时地址指向不会改变
- 列表
- 字典
- 集合
复制
在下面的代码中,y和x指向了同一片内存区域
1
21,2,3] x=[
y=x如果想要复制一份,指向不同的地址,可以使用copy()方法
1
2
3
4
5
61,2,3] x=[
y=x
#复制一份值 z=x.copy()
'0x%X,0x%X,0x%X'%(id(x),id(y),id(z))) print(
0x1FA6F616588,0x1FA6F616108,0x1FA6F5D6908也可以使用内置copy模块
1
2
31,2,3] x=[
import copy
#同:a=x.copy() a=copy.copy(x)
以上都是浅拷贝
切片就是一个浅拷贝
列表中的
enumerate
能够同时遍历下标和元素值1
2
3
4
5
6'a','b','c'] x=[
for index,letter in enumerate(x):
print('下标是{},对应的字母是{}'.format(index,letter))
下标是0,对应的字母是a
下标是1,对应的字母是b
下标是2,对应的字母是c
列表推导式
实现list分组
1
2
3
4
5
6
7
8for i in range(1,101)] m=[i
m
[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, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
3] for j in range(0,100,3)] n=[m[j:j+
n
[[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], [58, 59, 60], [61, 62, 63], [64, 65, 66], [67, 68, 69], [70, 71, 72], [73, 74, 75], [76, 77, 78], [79, 80, 81], [82, 83, 84], [85, 86, 87], [88, 89, 90], [91, 92, 93], [94, 95, 96], [97, 98, 99], [100]]
>>>
深拷贝
只能用copy模块实现
图1是浅拷贝
word1=words.copy()#或者word1=copy.copy(words)
,只拷贝了外面的一层图2是深拷贝
word2=copy.deepcopy(words)#深拷贝
元组:内置类
不可变类型,但可以查询
只有下面这两个方法!
index()
1
2
3
4
5
6
7
81,2,3,4,5) nums=(
4) nums.index(
3
9)#找不到会报错 nums.index(
Traceback (most recent call last):
File "<pyshell#133>", line 1, in <module>
nums.index(9)
ValueError: tuple.index(x): x not in tuplecount()
1
2
3
45) nums.count(
1
6) nums.count(
0
表示只有一个元素的元组,不能用
1
ages=(18)
因为
1
2
3
18) ages=(
type(ages)
<class 'int'>
需要加一个逗号
1
2
3
18,) ages=(
type(ages)
<class 'tuple'>
下面的代码会报错,因为int型不是可迭代对象
1
2
3
4
518)) print(tuple(
Traceback (most recent call last):
File "<pyshell#139>", line 1, in <module>
print(tuple(18))
TypeError: 'int' object is not iterable而字符串可以
1
2'hello')) print(tuple(
('h', 'e', 'l', 'l', 'o')list < == > tuple
1
2
3
4
5
6
7
81,2,3] x=[
# list ==>tuple tuple(x)
(1, 2, 3)
x
[1, 2, 3]
4,5,6) y=(
# tuple ==> list list(y)
[4, 5, 6]字典查询
key只能是不可变数据类型,一般使用字符串
若key重复,则后一个覆盖前一个
若查找的key不存在,则默认报错,可以使用get()方法修改
1
2
3
4
5
6
7
8
9
10
11'name':'fhs','city':'sd','age':12} person={
person
{'name': 'fhs', 'city': 'sd', 'age': 12}
'h'] person[
Traceback (most recent call last):
File "<pyshell#149>", line 1, in <module>
person['h']
KeyError: 'h'
'h') person.get(
'h')) print(person.get(
None默认值是None,可修改
1
2'h',199))#若找不到,则默认值为199 print(person.get(
199get方法只是对于当找不到key时的返回值情况,如果使用了get方法,并且找到了key,那么返回的仍旧是key对应的value
字典的增删改
直接用key修改
1
2
3
4'name': 'fhs', 'city': 'sd', 'age': 12} person={
'name']='dfg' person[
person
{'name': 'dfg', 'city': 'sd', 'age': 12}若key不存在,则会添加一个新的键值对
pop()删除
1
2
3
4
5
6person
'name': 'dfg', 'city': 'sd', 'age': 12} {
'name')#返回被删除的value person.pop(
'dfg'
person
'city': 'sd', 'age': 12} {popitem()
1 | person |
clear()
清空字典
字典的update()方法
用于合并两个字典
1
2
3
4
5'name':'fhs','city':'sd'} p1={
'height':199} p2={
p1.update(p2)
p1
{'name': 'fhs', 'city': 'sd', 'height': 199}+
可以连接两个而字符串、列表、元组,但字典不能!字典的迭代
方法一、for… in …
1
2
3
4
5
6
7p1
{'name': 'fhs', 'city': 'sd', 'height': 199}
for x in p1:#拿到的是key
print(x,'=',p1[x])
name = fhs
city = sd
height = 199方法二 、先获取所有key,然后遍历key
1
2
3
4
5
6
7p1
{'name': 'fhs', 'city': 'sd', 'height': 199}
for k in p1.keys():
print(k,'=',p1[k])
name = fhs
city = sd
height = 199方法三、获取所有value,但不能看到key
1
2
3
4
5
6
7p1
{'name': 'fhs', 'city': 'sd', 'height': 199}
for v in p1.values():
print(v)
fhs
sd
199方法四、使用dict.items()方法
1
2
3
4
5
6
7p1
{'name': 'fhs', 'city': 'sd', 'height': 199}
for item in p1.items():
print(item[0],'=',item[1])
name = fhs
city = sd
height = 199还可以拆包(最常用)
1
2
3
4
5
6
7p1
{'name': 'fhs', 'city': 'sd', 'height': 199}
for k,v in p1.items():
print(k,'=',v)
name = fhs
city = sd
height = 199用字典统计字母个数
1
2
3
4
5
6
7
8chars=['a','c','b','d','z','x','r','a','c','c','s','a','d','f','p']
dic={}
for letter in chars:
if letter not in dic.keys():
dic[letter]=1
else:
dic[letter]+=1
print(dic)1
{'a': 3, 'c': 3, 'b': 1, 'd': 2, 'z': 1, 'x': 1, 'r': 1, 's': 1, 'f': 1, 'p': 1}
在此基础上,取出现次数最多的那个字母
1
2
3
4
5
6
7
8
9
10#取出现次数最多的那个字母
max_cnt=0
for k,v in dic.items():
if v>max_cnt:
max_cnt=v
print(max_cnt)#3
for k,v in dic.items():
if v==max_cnt:
print(k)1
2a
c字典也有推导式
1
2
3
4
5dic={'a': 3, 'c': 3, 'b': 1, 'd': 2, 'p': 1}
dic1={}
dic1={v:k for k,v in dic.items()}
print(dic1)#注意若key相同,则后者覆盖前者
{3: 'c', 1: 'p', 2: 'd'}set
可以使用
()
表示,也可以使用{}
表示集合的特点:无序,不重复,所有没有查询的方法
add() 增加一个元素到随机位置
pop() 随机删除一个元素
remove() 删除一个指定的元素,不存在报错
union() 将多个集合合并 成一个新的集合
update() A.update(B) 将B拼接到A 里、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18s={1,2,3,4,1}
s.add('new')
print(s)
s.remove(1)
print(s)
s.pop()
print(s)
ss={'f','h'}
print(s.union(ss))
print(s)
s.update(ss)
print(s)1
2
3
4
5
6{1, 2, 3, 4, 'new'}
{2, 3, 4, 'new'}
{3, 4, 'new'}
{3, 4, 'h', 'new', 'f'}
{3, 4, 'new'}
{3, 4, 'f', 'h', 'new'}
集合支持许多运算,如
- 差集:-
- 交集: &
- 并集:|
- 异或: ^ ==> 求两个集合差集的并集
json
josn是个字符串
在Python中,可以用dumps方法实现dict和json的转化
1
2
3
4
5import json
dic={'name':'fhs','age':12}
x=json.dumps(dic)
print(x)
print(type(x))1
2{"name": "fhs", "age": 12}
<class 'str'>dumps将字典,元组,列表等转换为json
可以使用eval
函数将json字符串转换为原来的格式,如字典
1 | import json |
1 | {'name': 'fhs', 'age': 12} |
也可以使用json模块自带的loads
方法
1 | import json |
1 | {'name': 'fhs', 'age': 12} |
函数
传参可以按照对应位置依次填入,也可以指定
形参名=实参
,此时与顺序无关如果一个函数没有指定返回值,那么返回
None
Python函数中的参数不指定数据类型,但可以使用
:type
的格式来给出建议传入的类型,比如1
2def f(a:int,b:int):
pass使用glabal 可以在函数内部定义/更新全局变量
在Python里,只有函数能够分割作用域
在Python里,可return多个值
默认参数的使用
1
2
3
4
5
6def say(name,age,city='sd'):#默认参数city必须放在最后位置!
print('我是{},我{}岁了,来自{}'.format(name,age,city))
say('fhs',12)
我是fhs,我12岁了,来自sd默认参数必须放在最后!
可变参数
1
2def add(a,b,*args):
pass默认(缺省)参数应该放最后
1
2
3
4
5
6
7
8
9
10
11
12
13def add(a,b,*ar,mu=1):
c=a+b;
for i in ar:
c+=i
return mu*c
print(add(1,2,3,4))#不加mu则默认mu=1
print(add(1,2,3,4,2,mu=2))
#----------------
10
24总结一下:
*args
表示可变位置参数
**kwargs
表示可变关键字参数1
2
3
4
5
6
7
8
9
10
11
def add(a,b,*ar,mu=1,**kwargs):
print('kwargs={}'.format(kwargs))
c=a+b;
for i in ar:
c+=i
return mu*c
print(add(1,2,3,4,2,mu=2,x=0,y=6))
1 | kwargs={'x': 0, 'y': 6}#多余的参数以字典形式保存 |
在Python中,函数不能重名,否则后者会覆盖前者
变量名字不能与内置函数名重合,否则会发生一系列错误
在函数内部要修改全局变量的值,需要用
global
声明1
2
3
4
5
6
7
8
9cnt=0
def tell():
global cnt#!!!
cnt+=1
print("你好呀")
if cnt<3:
tell()
tell()1
2
3你好呀
你好呀
你好呀匿名函数:多用于表达一个简单的函数,基本上只调用一次
- 调用方法1:起个名字
1
2
3lambda a,b:a+b f=
1,2) f(
3- 调用方法2(常用):将这个匿名函数当作参数传给另一个函数使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17def cal(a,b,fn):
c=fn(a,b)
return c
def add(x,y):
return x+y
def minus(x,y):
return x-y
x1=cal(1,2,add)
x2=cal(10,5,minus)
print(x1,x2)
3
5上面的两个函数add和minus很简单,可以i用匿名函数来实现
1 | def cal(a,b,fn): |
sort方法
列表的sort方法会直接对原始列表进行排序
而sorted是内置函数,在排序时并不会改变原来的列表,而是会生成一个新的列表
对于字典,不可以直接使用sort方法,我们可以通过指定key来排序
(和C++的STL中的sort原理差不多)
1 | lis=[{'age':100,'height':1},{'age':99,'height':34},{'age':12345,'height':12}] |
也可以用匿名函数而不用上面的cmp()
1 | lis=[{'age':100,'height':1},{'age':99,'height':34},{'age':12345,'height':12}] |
filter() ==> 对可迭代对象进行过滤,得到的是一个可迭代对象
1
2
3
4
5
6
7
8
9ages=[1,2,3,4,5,66,77,88,9,90,11]
#第一个参数是函数,第二个参数是可迭代对象
x=filter(lambda one:one>18,ages)
for i in x:
print(i)
#x=list(x)
#print(x)1
2
3
466
77
88
90
这里有个不太理解的地方,下面的做法只能输出一个
1 | ages=[1,2,3,4,5,66,77,88,9,90,11] |
我的理解是,只要执行了1或者2中的任意一个,迭代器x就会变空了(每遍历到一个迭代器对象,就把它删除了)
map
让可迭代对象中的每一个元素都执行一下某一个相同操作
1
2
3
4
5
6
7ages=[1,2,3,4,5,66,77,88,9,90,11]
def add2(one):
return one+2
m=map(add2,ages)#让ages中的每个元素都加2
print(list(m))
>>>[3, 4, 5, 6, 7, 68, 79, 90, 11, 92, 13]当然使用匿名函数更简洁
1
2
3
4ages=[1,2,3,4,5,66,77,88,9,90,11]
m=map(lambda one:one+2,ages)#让ages中的每个元素都加2
print(list(m))
>>>[3, 4, 5, 6, 7, 68, 79, 90, 11, 92, 13]
reduce()
对某个可迭代对象执行某些操作,如累加
1
2
3
4
5
6
7
8
9
10
11
12from functools import reduce
ages=[i for i in range(1,101)]
print(reduce(lambda x,y:x+y,ages))
"""
#也可以不使用匿名函数
from functools import reduce
ages=[i for i in range(1,101)]
def m(x,y):
return x+y
print(reduce(m,ages))
"""
>>>5050也可以将字典组成的列表中的某个属性值相加
1
2
3
4
5
6
7
8
9
10
11
12
13
14from functools import reduce
lis=[{'age':3,'height':1},{'age':2,'height':34},{'age':1,'height':12}]
def m(x,y):
return x+y['age']
print(reduce(m,lis,0))#0是x的初始值,在这里必须指定
6
"""
#也可以使用匿名函数
from functools import reduce
lis=[{'age':3,'height':1},{'age':2,'height':34},{'age':1,'height':12}]
print(reduce(lambda x,y:x+y['age'],lis,0))
"""
注意区分map和reduce
reduce是不断地取迭代器中的下一个元素做某个操作,并将函数中前一个值更新为操作后的值,后一个取迭代对象中的下一个值,而map是对每个元素执行一次同样的操作;这里的操作都由那个
函数参数
指定
repr() 加个引号
1
21) repr(
'1'高阶函数
函数调用函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15def foo():
print("我是foo,我被调用了")
return 'foo'
def zx():
print("我是zx,我被调用了")
return foo()
y=zx()
print(y)
我是zx,我被调用了
我是foo,我被调用了
foo而若改成下面
1
2
3
4
5
6
7
8
9
10
11
12
13
14def foo():
print("我是foo,我被调用了")
return 'foo'
def zx():
print("我是zx,我被调用了")
return foo#这里返回的是函数名字
y=zx()
print(y)
我是zx,我被调用了
<function foo at 0x000001F6F36D83A8>原因是:
return foo
这里返回的是函数名字,它是<function foo at 0x000001F6F36D83A8>
,和上面的不同,这里并没有返回执行函数,只是返回了函数的名字而已改成如下,就和上面一样了
1
2
3
4
5
6
7
8
9
10
11def foo():
print("我是foo,我被调用了")
return 'foo'
def zx():
print("我是zx,我被调用了")
return foo#这里返回的是函数名字
y=zx()# y就代表函数foo
z=y()#相当于调用foo()
print(z)#那么就return 'foo'函数内部再嵌套一个函数(闭包)
1
2
3
4
5
6
7
8def outer():
def inner():
print("我是内部函数,我被调用了")
print("我是外部函数,我被调用了")
return inner()
outer()1
2我是外部函数,我被调用了
我是内部函数,我被调用了
1
2
3
4
5
6
7
8
9
10
def outer():
x=10#在外部函数里定义了一个变量x,是一个局部变量
def inner():
#在内部函数使用nonlocal修改外部函数的局部变量
nonlocal x
y=x+1
print('inner里的y=',y)
x=20#不是修改外部x变量,而是在inner函数内部又创建了一个新的变量x
return inner()
outer()
1
inner里的y= 11
计算代码运行耗时
1
2
3
4
5
6
7
8
9
10
11
12import time
start=time.time()#获取当前时间戳
print('start=',start)
x=0
for i in range(1,100000000):
x+=i
print(x)
end=time.time()
print('代码运行耗时{}秒'.format(end-start))
start= 1590586790.0947003
4999999950000000
代码运行耗时9.549989223480225秒装饰器(优化上面的计算程序耗时代码)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import time
def cal_time(fn):
print("我是外部,我被调用了")
print('fn={}'.format(fn))
def inner():
start=time.time()
fn()
end=time.time()
print("代码耗时",end-start)
return inner
def demo():
x=0
for i in range(1,100000000):
x+=i
print(x)
demo()
#第三件事,当再次调用cal_time时,其实调用的是inner函数
print("装饰后的demo={}".format(demo))1
2
3
4
5我是外部,我被调用了
fn=<function demo at 0x00000248930EB5E8>
4999999950000000
代码耗时 4.854478359222412
装饰后的demo=<function cal_time.<locals>.inner at 0x00000248930EB438>