python中拷贝、列表与字典生成式、高阶与内置高阶函数概述

一.‘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']
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值