【2019.6.2】python:json操作、函数、集合、random()、列表生成式、三元表达式
一、json操作:
json就是一个字符串,从文件中读取json,必须是json格式。j'son串中必须是双引号,不能有单引号,单引号不能转换
1.1使用:
import json #使用json先引用 d={ "error_code": 2, "msg": "无结果" } d2={ "error_code": 0, "stu_info": [ { "id": 314, "name": "矿泉水", "sex": "男", "age": 18, "addr": "北京市昌平区", "grade": "摩羯座", "phone": "18317155663", "gold": 100 }, { "id": 315, "name": "矿泉水", "sex": "女", "age": 27, "addr": "上海", "grade": "摩羯座", "phone": "18317155664", "gold": 100 } ] } with open(“abc.json","w",encoding='utf-8') as fr s=json.dumps(d2,ensure_ascii=False,indent=4) #字典转成字符串 #dumps()下,ensure_ascii=False 不转换编码,展示文件原内容,可正常展示中文 #dumps()下,Key前面增加空格:indent=4,加4个空格,空格可增加 #打开文件时,后缀加上json,可以有颜色。json 和txt都是文本文件 fr.write(s) fr.flush() #数据库不能存字典,所以要先转字符串 json.dump(d2,f,indent=4,ensure_ascii=False) #json.dump()把字符串转成字典,然后直接写入某个文件。
with open('abc',encoding='utf-8') as fr: #如果要是读的话,就不能用w模式,w模式会先清空文件 result=fr.read() dic=json.loads(result) #字符串转成字典 print(dic) result=json.loads(fr) #自动读取文件中的内容,然后转成字典 print(result) print(type(result)
二、切片
切片对有下标的类型的一种取值方式
l = ['xiaoming', 'xiaohei', 'xiaobai', 'jaojun','momo','coco'] print(l[0:1]) #切片是顾头不顾尾的,以上取到的是【1】之前的元素 print(l[:2]) #开始的索引不写,代表从0开始 print(l[0:]) #冒号后边的数字不写,取到最后一个元素 print(l[0:5:2]) #从下标为0,取到下标为4的,每隔一个元素去一个。最后一个数字是步长,步长的跨度是步长-1 print(l[-1:-3]) #从末尾数用负数 #字符串对切片也适用,只要通过下标取值都能用切片取值 s='adfadfege' print(s[1:3]) #最后的步长是负数的话,从右往左取 print(s[-1:-5:-2]) #倒数第一个,到第四个,隔一个取一个
2.2练习:浅拷贝、深拷贝
内存地址不变,为浅拷贝,内存地址变更为深拷贝
深拷贝:
l=[1,2,3,4]
l2=copy.deepcopy(l)
#练习: #循环过程中,不要删掉list中的元素,删除后会导致下标错乱 # li = [1,1,2,3,4,5,6,7,8,9] # li2 = [1,1,2,3,4,5,6,7,8,9] # for i in li: # if i%2!=0: # li.remove(i) # print(li) #结果1,2,4,6,8 # for i in li2: # if i%2!=0: # li.remove(i) # print(li) # li2=li # print(id(li)) # print(id(li2)) #print(id()):查看内存地址内存地址一样,内容就是样的 # for i in li2: # if i%2!=0: # li.remove(i) # print(li) # #结果1,2,4,6,8 # # li2=li[:] # print(id(li)) # print(id(li2)) #print(id()):查看内存地址内存地址一样,内容就是样的 # for i in li2: # if i%2!=0: # li.remove(i) # print(li) #2,4,6,8 #浅拷贝,深拷贝 #浅拷贝:内存地址没变 # l=[1,2,3,4] # l2=l #内存地址一样 # l.append('456') # l2.remove(12) #l2\l互相影响 # print(l2) #深拷贝: # l=[1,2,3,4] # l2=l[:] #内存地址不一样 # l.append('456') # l2.remove(12) #l2\l不互相影响 # print(l2) # #深拷贝: # import copy # l3=copy.deepcopy(l) #l3深拷贝l,l3和l不互相影响
三、函数:提高代码复用性
3.1定义函数:
# def smile(): # print('hhhha') #函数必须调用才会被执行 # smile() #什么时候想执行什么时候调用,函数名+()
定义函数时,如果写了参数,在调用时就必须传参,如果没写,可以不传参,定义时的参数为形参
3.1.1练习
实现判断输入的数据是否是小数
思路:
正小数:1.只有一个小数点
2.小数点左右两边都是整数
负小数:1.只有一个小数点
2.小数点右边都是整数,小数点左边只有一个负号
3.负号后边是一个整数
s=input("请输入一个数字") def is_float(): pass #占位 if s.count('.')==1: left,right= s.split('.') #多元赋值,将字符串s通过“.”分隔,并分分别赋给left、right if left.isdigit() and right.isdigit(): #isdigit只能判断整数 print("正整数") if left.count('-')==1 and left.statrswith('-') and left[1:].isdigit() and right.isdigit(): print("合法小数") #return True else: print('输入不合法') #return False else: print("不合法")
#调用:
is_float(1) #1为实参
is_float(1.5)
is_float(-1.25)
3.2函数返回值:return
#return作用:
#返回函数结果,在函数中遇到return,函数立即结束
def calc(a,b): result=a+b return result #result为函数返回值 sum=calc(1,2) print(sum)
3.2.2根据函数功能判断是否需要有返回值
#不需要return的例子 def write_file(file_name,content): with open(file_name,'w',encoding='utf-8') as fw: fw.write(content) #调用 write_file('test','hanmin,lala,keke')
3.2.3
def read_file(file_name): f=open(file_name,encoding="utf-8") result=f.read() #在函数中定义的变量,都是局部变量,只在函数中能用,出了函数就不能使用, return result print(result) res=read_file('test') print(res) #return作用: #返回函数结果,在函数中遇到return,函数立即结束
3.2.4 return 返回多个值,返回到一个元祖中,可以用多个参数来接收
def more(): name ='haha' age=18 score=98 return name,age,score #return 返回多个值,返回到一个元祖中,可以用多个参数来接收 mingzi,nianling,fenshu=more() #返回的是字符串 # mingzi,nianling=more() #结果会报错。不能用两个变量接受三个参数 yuanzu=more() #返回的是一个元组 print(type(mingzi)) print(yuanzu)
3.3默认值参数
#默认值参数 def regist(name,sex='女'): s="写进数据库%s,%s"%(name,sex) print(s) return s #有默认值的形参,不是必传的,如果传了就是传的值,如果没有传就是默认值。 print(regist('hanmin')) #不传sex,返回的结果就是默认值:女 regist('hanmin','男')
四、集合:set()是一种数据类型。集合天生可以去重,集合中没有重复的元素。集合是无序的
l=[1,1,2,3,5,4,2,3] #集合也是使用大括号。但不是key,value的 print(set(l)) #转换成集合
#集合可以循环取值
# #定义空集合:
# s=set()
4.添加元素
s.add(1) #添加元素,已经存在的元素不能再加进去 s.pop()#随机删除 s.remove(1) #删除元素
4.2集合可以取交集、并集、差集、对称差集
4.2.1交集:
xn=['jia','chang','zhang','wang'] zdh=['hm','smh','liu','wang','zhang'] xn_set=set(xn) zdh_set=set(zdh) #交集:intersection(): print(xn_set.intersection(zdh_set) ) #取xn_set和zdh_set交集 #&取交集 print(xn_set&zdh_set) #取交集,同上
4.2.2并集:union():把几个集合加在一起,重复的元素去重
print(xn_set.union(zdh_set)) #union() print(xn_set | zdh_set) #使用“|”符号,效果同上
4.2.3差集:在a集合中有,在b集合中没有的
#set.difference()差集: print(xn_set.difference(zdh_set)) #set1 - set2: print(xn_set - zdh_set)
4.2.4对称差集:把两个集合都有的删掉,留下不一样的,然后去重
#symmetric_difference(zdh_set) print(xn_set.symmetric_difference(zdh_set)) #^,效果同上 print(xn_set ^ zdh_set)
五、非空即真、非零即真:
5.1非空即真,对字典、列表、元组、字符串,均适用
s='' if s: #如果s为真 print('走if') else: print('else') #运行结果:else
user=input('username').strip() if user: print('不为空') else: print('空')
5.2非零即真
a=0 if a: print('真') #不是0,就是true,走if else: print('假') #是0,就是false.走else
#运行结果:假
六、列表生成式:
l=[] result=[i+1 for i in range(1,10)] print(result) #与以下代码一致: result2=[] for i in range(1,10): result2.append(i+1) print(result2)
s=[str(i).zfill(3) for i in range(1,20) if i >10] print(s) #执行顺序: #1.循环 #2、判断 #3.判断后再执行最前面的,根据判断留下最前面的。 #与以下代码一致: list=[] for i in range(1,20): if i>10: list.append(str(i).zfill(3)) print(list)
七、三元表达式:
#通过身份证号判断性别 id_card='152147188809081111' if int(id_card[-2])%2==0: print('女') else: print('男') #简单方式:用三元表达式写,以上方法同以下方法 sex='女' if int(id_card[-2])%2==0 else '男' print(sex) #三元表达式执行顺序: #先判断if,if后边的条件成立,值就是前边的值,如果if条件不满足,值就是后边的值
八、random模块:
8.1 random.randint():
import random #使用前先引用 #产生1-999999随机数 random.randint(): result=random.randint(1,999999) print(result) def sms_code(): #生成6位验证码 result=random.randint(1,999999) ver_code=str(result).result.zfill(6) return ver_code #生成5个: for i in range(5): print(sms_code())
8.2 random.sample():从一个字符串中,随机取几个,返回的是一个list
print(random.sample('798779dhkhis7987d9879aefd',5)) #随机取几个,返回的是一个list
#从前边传的参数中随便取5位,只要前边传的内容可以循环
random_list=random.sample('779897879789787897879',3) print(''.join(random_list)) #将list转为字符串,中间用‘’间隔
8.3 random.choice(‘56654465476’): 随机取一个值
print(random.choice('45454545646'))
8.4 random.uniform(1,9999),在这个范围内随机取一个小数
print(random.uniform(1,999))buyong
8.5 random.shuffle():洗牌,打乱顺序,必须传list,可用于产生随机用户名,手机号
list=[1,2,3,4,5,6,7,8] random.shuffle(list) print(list)
8.6 import string:
import string print(string.digits) #0-9的所有正整数 print(string.ascii_lowercase) #所有小写字母 print(string.ascii_uppercase) #所有大写字母 print(string.ascii_letters) #所有大写加小写字母 print(string.punctuationg) #所有特殊符号
8.7在一个范围内随机生成一个小数
a=random.uniform(1,10) #1~10之前生成随机小数 print(a) print(round(a,2)) #保留两位小数
九、练习:产生一批用户名,长度在6-12之间,产生这一批用户名不能重复,用户名需要以字母开头,必须包含字母和数字
思路:
1、循环,传入的数字是多少,就产生多少条
2、随机产生一个6-12之间的数字当做长度
3、不能重复用的就用集合
4、判断产生的用户名第一个元素是否不为整数
def gen_username(num):#产生用户名 all_username = set() while len(all_username)!= num: length = random.randint(6,12) temp = random.sample(string.digits+string.ascii_letters,length)#用户用 if set(temp) & set(string.digits) and set(temp) & set(string.ascii_letters) and \ not temp[0].isdigit(): username = ''.join(temp) all_username.add(username+'@163.com'+'\n') return all_username print(gen_username(3))