xone

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

多级菜单

  • 多级菜单
  • 可依次选择进入各子菜单
  • 所需新知识点:列表、字典
#!/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','123','546'}
li={'alex',454,'lhf',552}
print(py&li)
print(py.intersection(li))

以上代码运行结果

{'lhf', 'alex'}
{'lhf', 'alex'}

并集

py={'alex','lhf','123','546'}
li={'alex',454,'lhf',552}
print(py|li)

以上代码运行结果

{'546', 454, 552, 'alex', 'lhf', '123'}

差集

py里面存在,li里面不存在的

py={'alex','lhf','123','546'}
li={'alex',454,'lhf',552}
print(py-li)
print(py.difference(li))

以上代码运行结果

{'123', '546'}
{'123', '546'}

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','123','546'}
li={'alex',454,'lhf',552}
print(py^li)
print(py.symmetric_difference)

以上代码运行结果

{552, '546', '123', 454}
{552, '546', '123', 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 == '1':
        username = input('请输入用户名')
        passwd = input('请输入密码')

        is_login = login(username,passwd)

        if is_login:
            print('登录成功')
        else:
            print('登录失败')
    elif choice == '2':
        username = input('请输入用户名')
        passwd = input('请输入密码')
        if isregister(username):
            print('用户已存在')
            return
        else:
            if register(username,passwd):
                print('注册成功')
            else:
                print('注册失败')

main()

文件编码

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 













 

posted on 2016-10-25 11:47  周小百  阅读(383)  评论(0编辑  收藏  举报