python基础三

多级菜单

  • 多级菜单
  • 可依次选择进入各子菜单
  • 所需新知识点:列表、字典
#!/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()

文件编码

python基础三

上一篇:Android开发之ListView添加多种布局效果演示


下一篇:POJ1769 Minimizing maximizer(DP + 线段树)