一.‘is’和’=='的区别
1、概念
==:比较的是二者的值(value)和数据类型(type)
is:比较的是二者的值(value)和数据类型(type)和内存地址空间(id)
2、验证
>>> a = [1,2,3]
>>> b = a
>>> id(a) #查看a的内存地址空间
140578869413896
>>> id(b) #查看b的内存地址空间
140578869413896 #与a相同
>>> c = [1,2,3] #重新建立一个列表c,与a的数据类型和值相同
>>> id(c) #查看c的内存地址空间
140578869413704 #与a不同,因为列表是可变的数据类型,所以在新建时哪怕是相同值,也会给一个新的内存地址空间
>>> a == b #a是否==b
True #为真
>>> a == c #a是否==c
True #为真
>>> a is b #a是否isb
True #为真
>>> a is c #a是否isc
False #为假,因为is时还要比较内存地址空间(id)
二.深拷贝和浅拷贝的区别
1、概念
深拷贝:copy.deepcopy()
浅拷贝:copy.copy()
2、验证
可变数据类型:
>>> import copy #由于深浅拷贝是内置的模块,所以需要加入
>>> a = [1,2]
>>> b = [3,4]
>>> c = [a,b]
>>> c
[[1, 2], [3, 4]] #c为可变数据类型
>>> d = copy.copy(c) #d为c的浅拷贝
>>> e = copy.deepcopy(c) #e为c的深拷贝
>>> id(c) #查看c的id
140578869413896
>>> id (d) #查看d的id(因为是拷贝,所以不同)
140578748913480
>>> id (e) #查看e的id(因为是拷贝,所以不同)
140578748913544
>>> id (c[1]) #查看c中元素的id
140578869413960
>>> id (d[1]) #查看d中元素的id(与c的相同,浅拷贝时,内容元素不会拷贝,所以id不发生改变,仅仅是指向)
140578869413960
>>> id (e[1]) #查看e中元素的id(与c不同,因为深拷贝时,内容元素也会重新拷贝一份,所以id发生改变)
140578748915080
>>> id (b) #c中元素b的id与c[1]、d[1]相同,因为这两个都是指向该内存地址空间
140578869413960
不可变数据类型:
不可变数据类型的copy.copy()没有浅拷贝的概念,在执行此操作时,仅仅操作的是一个指向,不改变内存地址空间。
(1)不可变数据类型中,元素也为不可变数据类型时
若不可变数据类型中的元素也都为不可变数据类型,那么copy.copy()与copy.deepcopy()的作用相同,都仅仅是一个引用与指向,不改变内存地址空间。
>>> a = 1
>>> b = 2
>>> c = (a,b) #元组c为不可变数据类型,a和b也都为不可变数据类型
>>> c
(1, 2)
>>> d = copy.copy(c) #d是元组c的copy.copy()
>>> e = copy.deepcopy(c)#e是元组c的copy.deepcopy()
>>> id (c) #查看c的id
140578869414600
>>> id (d) #查看d的id,因为c是不可变数据类型,所以此处不改变内存地址空间
140578869414600
>>> id (e) #查看e的id,因为c是不可变数据类型,所以此处不改变内存地址空间
140578869414600
>>> id (c[1]) #查看c中第一个元素的内存地址空间
9322496
>>> id (d[1]) #查看d中第一个元素的内存地址空间,与c相同
9322496
>>> id (e[1]) #查看e中第一个元素的内存地址空间,与c相同
9322496
>>> id (b) #查看b的内存地址空间,其他都直接指向b的内存地址空间
9322496
(2)不可变数据类型中,元素含有可变数据类型元素时
不可变数据类型中含有可变数据类型的元素时,浅拷贝仅是一个指向,不改变内存地址空间,深拷贝仍为深拷贝。
>>> a = [1,2]
>>> b = [3,4]
>>> c = (a,b) #c是不可变数据类型,c中的元素a、b是可变数据类型
>>> d = copy.copy(c) #d为c的浅拷贝
>>> e = copy.deepcopy(c) #e为c的深拷贝
>>> id(c) #查看c的id
139908984441160
>>> id (d) #查看d的id,浅拷贝只是引用,所与d的id与c相同
139908984441160
>>> id (e) #查看e的id,因为是深拷贝,所以e的id与c不同
139908983814856
>>> id (c[1]) #查看c[1]的id
139908984440648
>>> id (d[1]) #查看d[1]的id,因为是浅拷贝,所以与c[1]相同
139908984440648
>>> id (e[1]) #查看e[1]的id,因为是深拷贝,所以与c[1]不相同
139908863941768
三.列表生成式
1、列表生成式写法举例
题1:找出1~10之间的所有偶数
print([i for i in range(1,11) if i %2 == 0])
# [2, 4, 6, 8, 10]
题2:s1=‘ABC’,s2=‘123’,输出列表[‘A1’, ‘A2’, ‘A3’, ‘B1’, ‘B2’, ‘B3’, ‘C1’, ‘C2’, ‘C3’]。
s1='ABC'
s2='123'
#for i in s1:
# for b in s2:
# print(i+b)
print([i+b for i in s1 for b in s2]) #该列表生成式就与上面的for循环一个意思
#['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
2、练习:结合列表生成式与函数,找出1~100间的所有素数(素数即为只能被1和本身整除的数)
def sushu(num):
for n in range(2, num):
if num % n == 0:
return False
else:
return True
print([i for i in range(2, 100) if sushu(i)]) #当函数返回False时,该i会被丢弃,返回True时,i才会输出
#[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
四.字典生成式
需求1:假设有20个学生,学生的分数在60~100之间,筛选出成绩在90分以上的学生
import random
studentinfo = {}
for i in range(20):
name = 'abc' + str(i)
score = random.randint(60, 100)
studentinfo[name] = score
# enoughdict = {}
# for name,score in studentinfo.items():
# if score > 90:
# enoughdict[name]=score
# print(enoughdict)
dic1={name:score for name,score in studentinfo.items() if score > 90}
print({name:score for name,score in studentinfo.items() if score > 90})
#{'abc0': 96, 'abc13': 94, 'abc16': 91} #输出结果
需求2:将所有的key值都变成大写
print({k.upper():v for k,v in dic1.items()})
#{'ABC0': 96, 'ABC13': 94, 'ABC16': 91} #输出结果
需求3:将大小写的key值合并,统一以小写输出
dic2=dict(a=1,A=2,b=3)
print({i.lower():dic2.get(i.upper(),0) + dic2.get(i.lower(),0) for i in dic2}) #意为,取出dic2中的key值给i赋值,新生成字典的小写i的value值为:dic2字典中小写i对应的value值(若没有,则取0)+dic2字典中大写i对应的value值(若没有,则取0)
#{'a': 3, 'b': 3}
五.高阶函数
实参是一个函数名
函数的返回值是一个函数
print(abs(10))
#10
#函数本身也可以赋值给变量,变量可以指向函数
f=abs
print(f(-10))
#10
def fun(x,y,f):
return f(x),f(y)
print(fun(-10,58,abs))
#(10, 58)
六.内置高阶函数
1、map
map():接收两个参数,一个是函数,一个是序列
map将传入的函数依次作用到序列的每一个元素,并且把结果作为新的序列返回
#对一个序列[-5,1,3,-2]的每一个元素求绝对值
print(list(map(abs,[-5,1,3,-2])))
#[5, 1, 3, 2]
#对每个元素求阶乘
import random
def f(x):
res=1
for i in range(1,x+1):
res = res*i
return res
li=[random.randint(2,5) for i in range(10)]
print(list(map(f,li)))
#[24, 24, 6, 120, 120, 6, 120, 6, 6, 24]
2、reduce
#reduce():把一个函数作用在一个序列上,这个函数必须接收两个参数
#reduce把结果继续和序列的下一个元素做累计运算
#reduce(f,[x1,x2,x3,x4])=f(f(f(x1,x2),x3),x4)
#python2中:reduce是内置函数
#python3中:需要用from functools import reduce
from functools import reduce
def multi(x,y): #表示需要接收2个参数
return x * y
print(reduce(multi,range(1,10)))#9的阶乘
def add(x,y):
return x+y
print(reduce(add,range(1,101))) #将1~100想加的和
3、filter
filter过滤函数
和map()类似的,也接收一个函数和一个序列
但是和map()不同的是,filter()把传入的函数依次作用于
每个元素,然后根据返回值是True或者False决定保留还是丢弃该元素
def isodd(num):
if num % 2 == 0:
return True
else:
return False
print(list(filter(isodd,range(100))))
4、sort
list = [6,7,8,9,1,2,34]
# list.sort()
# print(list)
# 不改变原来的列表内容,生成一个新的列表
list2 = sorted(list)
print(list)
print(list2)
list2 = [6,8,-8,-4,2,3,4,7,8]
list2.sort()
print(list2)
list3 = sorted(list2,key=abs)
print(list3)
s = ['da','Ffsf','FSF','das']
print(s)
print(sorted(s))
print(sorted(s,key=str.lower))
print(sorted(s,key=str.upper))
七.匿名函数
匿名函数的关键字为 lambda
冒号前面是 形参 冒号后面是返回值
from functools import reduce
def add(x,y):
return x+y
print(reduce(add,range(10)))
print(reduce(lambda x,y:x+y,range(10)))
def mypow(x):
return x ** 2
print(list(map(lambda x:x**2,range(5))))
def isood(num):
return num % 2 == 0
print(list(filter(lambda x:x%2==0,range(10))))
八.综合练习题
综合练习题1:
对于一个十进制的正整数,定义f(n)为其各位数字的平方和,如:
f(15)=1**2+5**2=26
f(207)=2**2+0**2+7**2=53
下面给出三个正整数k,a,b,需要计算有多少个正整数n满足条件:a<=n<=b且k*f(n)=n
输入:3个正整数k,a,b,k>=1,a,b<=10**18,a<=b;
输出:输出答案(满足条件的正整数n的个数)
def f(n):
n = str(n)
sum = 0
for i in n:
sum += int(i)**2
return sum
x=input("请输入三个整数")
l=x.split(" ")
k,a,b=l
num=0
for n in range(1,int(b)+1):
if int(a) <= n <= int(b) and int(k)*f(n)==n:
num += 1
print(num)
#请输入三个整数51 5000 10000
#3
综合练习题2:
给定一个正整数,编写程序计算有多少对质数的和等于输入的这个正整数,并输出结果。输入值小于1000。如:输入10,结果应为2
输入描述:输入包括一个整数n(3<=n<=1000)
输出描述:输出对数(有多少对质数)
def sushu(num):
for n in range(2, num):
if num % n == 0:
return False
else:
return True
count = 0
sushulie=[i for i in range(2, 100) if sushu(i)]
num=int(input("请输入一个正整数:"))
for x1 in sushulie:
if num-x1 in sushulie and x1<=num-x1:
count += 1
print(count)
#请输入一个正整数:10
#2
综合练习题3:
字符串大写改小写,非字符串去掉
lie=['AAA','bbb','Ccc',1,54,2.3,True]
lie2=[i for i in lie if isinstance(i,str)]
print([a.lower() for a in lie2])
# ['aaa', 'bbb', 'ccc']
综合练习题4:
找出/var/log目录中所有以.log结尾的文件名或者目录名
import os
print([filename for filename in os.listdir('/var/log') if filename.endswith(".log")])
#['yum.log', 'boot.log', 'wpa_supplicant.log', 'Xorg.0.log']