多级菜单
- 多级菜单
- 可依次选择进入各子菜单
- 所需新知识点:列表、字典
#!/usr/bin/env python
# -*- coding: utf-8 -*-
menu = {
'北京':{
'海淀':{
'五道口':{
'soho':{},
'网易':{},
'google':{}
},
'中关村':{
'爱奇艺':{},
'汽车之家':{},
'youku':{},
},
'上地':{
'百度':{},
},
},
'昌平':{
'沙河':{
'老男孩':{},
'北航':{},
},
'天通苑':{},
'回龙观':{},
},
'朝阳':{},
'东城':{},
},
'上海':{
'闵行':{
"人民广场":{
'炸鸡店':{}
}
},
'闸北':{
'火车战':{
'携程':{}
}
},
'浦东':{},
},
'山东':{},
} current_level = menu
last_level = [] while True:
for key in current_level:
print(key)
choice = input(">>:").strip()
if len(choice) ==0:break
if choice =='b':
if len(last_level)==0:break
current_level = last_level[-1]
last_level.pop()
if choice not in current_level:continue
last_level.append(current_level)
current_level = current_level[choice]
字典
注意:当我们想循环删除字典里的value时,用下面的方法
dic = {'k1':'v1','k2':'v2','k3':'v3'} for k in list(dic.keys()):
if 'k1' in k:
del dic[k]
print(dic)
以上代码运行结果:
{'k3': 'v3', 'k2': 'v2'}
查询
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} print(dic['name'])
print(dic.get('namedf'))#用get,如果没有这个值,查询不会报错
以上代码运行结果
alex
None
add
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic['gender']='female'
print(dic)#打印字典是无序的
以上代码运行结果
{'age': 18, 'gender': 'female', 'name': 'alex'}
change
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic['name']='lhf'
print(dic)
以上代码运行结果
{'name': 'lhf', 'age': 18}
del
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} del dic['name']
print(dic)
以上代码运行结果
{'age': 18}
字典里嵌入其它数据类型
dic1={
1:'alex',
'name':'lhf',
(1,2,3):{'age':18},
'name':'alex'
} print(dic1[1])
print(dic1['name'])
print(dic1[(1,2,3)])
print(dic1[(1,2,3)]['age'])
以上代码运行结果
alex
alex
{'age': 18}
18
字典的其它用法
dic1=dict.fromkeys('abc',1)
print(dic1)
以上代码运行结果(注意:此处类似浅拷贝)
{'b': 1, 'c': 1, 'a': 1}
dict.fromkeys(seq[, value]))
dict.get(key, default=None)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic2 =dict.fromkeys(['a','b'],1)
print(dic2)
print(dic.get('name'))
以上代码运行结果
{'b': 1, 'a': 1}
alex
dict.items()
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} for k,v in dic.items():
print(k,v)
print(dic.keys())
for i in dic.keys():
print('key is %s,value is %s'%(i,dic[i]))
以上代码运行结果
age 18
name alex
dict_keys(['age', 'name'])
key is age,value is 18
key is name,value is alex
指定删除
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic.pop('name')
print(dic)
以上代码运行结果
{'age': 18}
随机删除
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic.popitem()
print(dic)
以上代码运行结果
{'name': 'alex'}
dict.setdefault(key, default=None)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} dic.setdefault('gender',[]).append('male')
dic['gender'].append('female')
以上代码运行结果
{'age': 18, 'name': 'alex', 'gender': ['male', 'female']}
dict.update(dict2)
__author__ = "zhou"
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18}
dic1 = {'gender':'male','name':'ldf'} dic.update(dic1)
print(dic)
以上代码运行结果
{'name': 'ldf', 'age': 18, 'gender': 'male'}
常用的取字典里面键值的方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
dic={'name':'alex','age':18} for k in dic:
print(k,dic[k])
for i in dic.values():
print(i)
以上代码运行结果
age 18
name alex
18
alex
深浅拷贝
不同数据类型在内存中的存址方式:
字符串,数字,在内存中一次性创建,不能被修改,只要修改,就再创建。
列表,在内存中以类似链表,记录上一个元素的位置,以及下一个元素的位置,不连续的方式存储。方便插入、添加操作
字符串和数字:
在python里拷贝、赋值时地址都一样。理论上拷贝应该不一样,但是python内部做了优化,结果导致地址一样。
列表,元组,字典:
赋值
只是创建一个变量,该变量指向原来内存地址,如:
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1
copy 浅复制 复制时只会复制父对象,而不会复制对象的内部的子对象。
deepcopy 深复制 复制对象及其子对象
In [55]: a = [11,22,33] In [56]: b = a In [57]: import copy In [58]: c = copy.deepcopy(a) In [59]: id(a)
Out[59]: 139989431745672 In [60]: id(b)
Out[60]: 139989431745672 In [61]: id(c)
Out[61]: 139989482468296 In [62]: a.append(44) In [63]: a
Out[63]: [11, 22, 33, 44] In [64]: b
Out[64]: [11, 22, 33, 44] In [65]: c
Out[65]: [11, 22, 33]
In [89]: a = [11,22,33] In [90]: b = [44,55,66] In [91]: c = [a,b] In [92]: e = copy.deepcopy(c) In [93]: c
Out[93]: [[11, 22, 33], [44, 55, 66]] In [94]: e
Out[94]: [[11, 22, 33], [44, 55, 66]] In [95]: a.append(66) In [96]: c
Out[96]: [[11, 22, 33, 66], [44, 55, 66]] In [97]: e
Out[97]: [[11, 22, 33], [44, 55, 66]]
集合
创建集合
s1 = set()
s = {11,22}
交集
py={'alex','lhf','',''}
li={'alex',454,'lhf',552}
print(py&li)
print(py.intersection(li))
以上代码运行结果
{'lhf', 'alex'}
{'lhf', 'alex'}
并集
py={'alex','lhf','',''}
li={'alex',454,'lhf',552}
print(py|li)
以上代码运行结果
{'', 454, 552, 'alex', 'lhf', ''}
差集
py里面存在,li里面不存在的
py={'alex','lhf','',''}
li={'alex',454,'lhf',552}
print(py-li)
print(py.difference(li))
以上代码运行结果
{'', ''}
{'', ''}
difference_update()
找s1中存在,s2中不存在的集合,更新自己
s1 = {1, 2, 3, 'fds', 4, 5, 65, 52}
s2 = {1, 2, 3}
print(s1.difference_update(s2))
print(s1)
以上代码运行结果
None
{65, 4, 5, 52, 'fds'}
对称差集
py={'alex','lhf','',''}
li={'alex',454,'lhf',552}
print(py^li)
print(py.symmetric_difference)
以上代码运行结果
{552, '', '', 454}
{552, '', '', 454}
是否父集
s1={1,2,3,4,5}
s2={1,2} print(s1>=s2)
print(s2.issubset(s1))
以上代码运行结果
True
True
是否子集
s1={1,2,3,4,5}
s2={1,2} print(s2<=s1)
print(s1.issuperset(s2))
以上代码运行结果
True
True
将元组转换为集合
t1=(1,2,3)
s1 = set(t1)
print(s1)
以上代码运行结果
{1, 2, 3}
集合的其它内置方法
s1 = {1,2,3,'fds',4,5,65,52}
s1.update('e')
s1.update((1,2,3,4))
s2 ={'e','g',5}
s1.update(s2)
s1.update('hello')
print(s1)
以上代码运行结果
{65, 2, 3, 4, 5, 1, 'e', 'h', 'g', 52, 'fds', 'o', 'l'}
增加
s1 = {1,2,3,'fds',4,5,65,52} s1.add('hello')
print(s1)
以上代码运行结果
{65, 2, 3, 4, 5, 1, 'hello', 52, 'fds'}
随机删除(当所有元素为数字时不随机)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
s1 = {1,2,3,'fds',4,5,65,52} s1.pop()
print(s1)
以上代码运行结果
{2, 3, 4, 5, 1, 52, 'fds'}
指定删除
s1 = {1,2,3,'fds',4,5,'ggh',52} s1.remove(2)
s1.remove(3)
print(s1)
以上代码运行结果
{1, 4, 5, 'fds', 'ggh', 52}
不报错的删除
s1 = {1,2,3,'fds',4,5,'ggh',52}
s1.discard('a')
print(s1)
以上代码运行结果
{1, 2, 3, 'ggh', 4, 5, 'fds', 52}
文件处理
# open(文件名,模式,编码)
# 默认只读
打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作。
打开文件的模式有:
- r ,只读模式【默认】
- w,只写模式【不可读;不存在则创建;存在则清空内容;】
- x, 只写模式【不可读;不存在则创建,存在则报错】
- a, 追加模式【不可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+, 读写【可读,可写】
- w+,写读【可读,可写】
- x+ ,写读【可读,可写】
- a+, 写读【可读,可写】
"b"表示以字节的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
注:以b方式打开时,读取到的内容是字节类型,写入时也需要提供字节类型
指针
一、先介绍下file读入的控制函数:
seek(offset,where): where=0从起始位置移动,1从当前位置移动,2从结束位置移动。当有换行时,会被换行截断。seek()无返回值,故值为None。
# 将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。但如果提供了where参数就不一定了,where可以为0表示从头开始计算,1表示以当前位置为原点计算。2表示以文件末尾为原点进行计算。需要注意,如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。
seek()的三种模式:
(1)f.seek(p,0) 移动当文件第p个字节处,绝对位置
(2)f.seek(p,1) 移动到相对于当前位置之后的p个字节
(3)f.seek(p,2) 移动到相对文章尾之后的p个字节
tell(): 返回文件的当前位置,即文件指针当前位置,以文件开头为原点,受seek、readline、read、readlines影响,不受truncate影响
r+
w,末尾追加,指针到最后,但是依然能读到最开始未读完的内容,例如:开始用f.read(1),1后面未读的内容依然在写入之后能读到,seek后,从当前指针位置往后写。
r,指针为0,起始位置
#!/usr/bin/env python
# -*- coding: utf-8 -*- a = "abcd\ngsgdsf\ndsf"
f1 = open("test.txt","w")
f1.write(a)
#查看当前指针位置
print(f1.tell())
f1.close() f2 = open("test.txt","r")
content1 = f2.readline()
print(content1)
content2 = f2.readline()
print(content2)
#查看当前指针位置
print(f2.tell())
#调整指针到文件开头
f2.seek(0,0)
#查看当前指针位置
print(f2.tell())
content3 = f2.readline()
print(content3)
f2.close()
普通方式打开:默认以utf-8解码打开
从文件上读出来的字节内容--->通过utf-8解码成字符串打开
f = open('new.txt', 'r',encoding='utf-8')
data = f.read()
f.close()
print(data)
以普通方式写入:要写入特定编码的文本文件,请给open()
函数传入encoding
参数,将字符串自动转换成指定编码。
python默认以utf-8编码后写入,
如果想以gbk的方式写入,
方式一:以b方式打开,然后f.write(bytes('中国人',encoding='gbk')写入
方式二:给open()
函数传入encoding
参数,字符串将自动转换成指定编码。
f = open('h1.log','w',encoding='gbk)
f.write('中国人')
f.close()
以bytes方式打开:
从文件上读出来的字节内容,不需要进行utf-8解码,写入的时候要以字节方式写入
f = open('h1.log','wb')
f.write(bytes('a',encoding='utf-8'))
f.close() f = open('h1.log','rb')
data = f.read()
f.close()
print(data,ord(data)) str_data = str(data,encoding='utf-8')
print(str_data)
以上代码执行结果(这里b'a'里面的a,表现形式是a,本质上是二进制)
b'a' 97
a
对于 ASCII 字符串,可以直接使用 b'xxxx' 赋值创建 bytes 实例,
readline,只读取一行
readlines:读取所有行,放在一个列表里
truncate(num):截取文件前num个,会直接修改文件
flush:强行刷入硬盘
查看文件前五行(方法一)
f = open("file", encoding="utf-8")
for index,line in enumerate(f.readlines()):
if index < 5:
print(line.strip())
else:
break
f.close()
以上代码运行结果
1.周智明
2.周智明
3.周智明
4.周智明
5.周智明
查看文件前五行(方法二)
# !/usr/bin/env python
# -*- coding: utf-8 -*-
f = open("file", encoding="utf-8")
for i in range(5):
print(f.readline().strip())
f.close()
以上代码运行结果
1.周智明
2.周智明
3.周智明
4.周智明
5.周智明
查看文件前五行(方法三,推荐,前两种都会把前5行都读到内存,第三种只会读取一行到内存。)
# !/usr/bin/env python
# -*- coding: utf-8 -*- f = open("file", encoding="utf-8")
line_nu = 0
for line in f:
if line_nu <5:
print(line.strip())
line_nu +=1
f.close()
以上代码运行结果
1.周智明
2.周智明
3.周智明
4.周智明
5.周智明
大文件复制方法
#!/usr/bin/env python
# -*- coding: utf-8 -*- old_file_name = input("请输入要复制的文件名:") #打开要复制的文件
old_file = open(old_file_name,"r") #为复件命名
position = old_file_name.rfind(".")
new_file_name = old_file_name[:position] + "[复件]" + old_file_name[position:] #新建一个文件
new_file = open(new_file_name,"w") #从旧文件读取数据并写到新文件 while True:
content = old_file.read(1024)
if len(content)==0:
break
new_file.write(content) #关闭两个文件
old_file.close()
new_file.close()
with open() as obj复制文件
可以同时打开多个文件,且操作完自动关闭
with open('h1.log','r',encoding='utf-8') as obj1, open('h2.log','w',encoding='utf-8') as obj2:
for line in obj1:
obj2.write(line)
利用文件处理实现验证用户登录:
db
admin$123
zzz$111
login.py
def login(username,passwd):
'''
用于验证登录
:param username:
:param passwd:
:return: True登录成功,False登录失败
'''
with open('db', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
line_list = line.split('$')
# print(line_list)
if username == line_list[0] and passwd == line_list[1]:
return True
return False def isregister(username):
'''
验证用户名是否注册
:param username:
:return:
'''
with open('db','r',encoding='utf-8') as f:
for line in f:
line = line.strip()
line_list = line.split('$')
if username == line_list[0]:
return True
return False def register(username,passwd):
'''
注册用户
:param username:
:param passwd:
:return:
'''
with open('db','a',encoding='utf-8') as f:
temp = '\n%s$%s'%(username,passwd)
f.write(temp)
return True def main():
'''
登录主函数
:param username:
:param passwd:
:return:
'''
choice =input('1、登录 2、注册>>')
if choice == '':
username = input('请输入用户名')
passwd = input('请输入密码') is_login = login(username,passwd) if is_login:
print('登录成功')
else:
print('登录失败')
elif choice == '':
username = input('请输入用户名')
passwd = input('请输入密码')
if isregister(username):
print('用户已存在')
return
else:
if register(username,passwd):
print('注册成功')
else:
print('注册失败') main()