python數據類型、編碼

1、數字類型使用

可變與不可變類型

  • 可變:在值改變的狀況,若是id不變,證實就是在修改原值,便可變類型
  • 不可變:在值改變的狀況,若是id也跟着變,證實根本沒有修改原值,即不可變類型

int基本使用

1.經常使用操做+內置方法git

  算數運算,比較運算算法

2.該類型總結bash

  • 存一個值
  • 不可變類型
 x=10 print(id(x)) x=11 print(id(x)) 

float基本使用

1.經常使用操做+內置方法app

  算法運算,比較運算編輯器

2.該類型總結ide

  • 存一個值
  • 不可變類型

 x=10.1 print(id(x)) x=11.1 print(id(x)) 測試

2、字符串使用

str基本使用

1.經常使用操做+內置方法google

索引取值

(正向取+反向取):只能取   編碼

msg="hello world"
print(msg[1])
print(msg[5])
print(msg[-1])
print(msg[-3])

切片

從一個大字符串中切除一個子字符串(顧頭不顧尾,步長)spa

msg="hello world"
print(msg[1:3])
print(msg[6:11])
print(msg[6:11:2]) #world #wrd

# 倒着取值(瞭解):注意方向要一致
print(msg[6:])
print(msg[-1:-6:-1])
print(msg[-1::-1])
print(msg[::-1])

長度len

msg="hello world" print(len(msg)) # 長度是11,索引最大到10

成員運算in 和not in 

判斷一個子字符串是否存在於一個大字符串中

msg="hello world hello momo"
print('momo' in msg)
print('world' in msg)
print('hello' not in msg)
print(not 'hello' in msg)

移除空白strip

msg='     mogu       '
res=msg.strip() # 默認去除的是字符串左右兩邊的空格
print(msg)
print(res)

# strip會從左往右開始吃空格,直到碰到一個非空格爲止
# 右面相同的原理
#ps:strip並無修改原值,是產生一個新值

msg='******mo****gu*****'
print(msg.strip('*'))

msg='-&!^%aaaa-!&^%'
print(msg.strip('!-&^%'))

切分split

把一個字符串按照某種分隔符切成一個列表

info='root:x:0:0:admin user:/root:/bin/bash'
res=info.split(':',maxsplit=-1)
print(res,type(res))
print(res[0])
l=['mogu',123,'chimogu']
s1=':'.join(l) #把列表又轉成了字符串(前提是列表中全部元素均爲字符串)
print(s1,type(s1))

循環

  while循環取值

1 msg='hello world'
2 i=0
3 while i < len(msg):
4     print(msg[i])
5     i+=1

  for循環取值

msg='hello world'
for item in msg:
print(item)

大小寫切換

# 二、lower,upper
print('aaAbCCC'.lower())
print('aaAbCCC'.upper())

判斷以什麼開頭(startswith)什麼結尾(endswith)

print('xiaomogu  like  mogu'.startswith('xiao'))
print('xiaomogu  like  mogu'.endswith('gu'))

格式化輸出format

print('my name is %s my age is %s' %(18,'mogu'))
print('my name is {name} my age is {age}'.format(age=18,name='mogu'))

print('my name is {} my age is {}'.format(18,'mogu'))
print('my name is {0}{0}{0} my age is {1}'.format(18,'mogu'))

replace 替換操做

msg='my name is xiaomogu,xiaomogu say hello'
print(msg.replace('xiaomogu','xiaonvhai',1))

isdigit

只有在字符串中包含純數字的狀況下結果才爲True

print('10123'.isdigit())

其餘

#center,ljust,rjust,zfill

分別對應中央位  左對齊   右對齊   右對齊以0爲佔位符
print('**************%s*************************'  %'mogu')
print('mogu'.center(50,'*'))
print('mogu'.ljust(50,'='))
print('mogu'.rjust(50,'-'))
print('mogu'.rjust(50,'0'))
print('mogu'.zfill(50))
# expandtabs     end=' ' 取消print默認的換行符\n
print('aaabbbb',end='     ')
print('cccc',end='')
print('aaaa\nbbbb',end='')
print('aaa\tbbb'.expandtabs(tabsize=3))
#\n 表明換行符  \t  表明tab鍵 (製表符)

總結

  • 存一個值
  • 有序
  • 不可變

3、列表使用

list基本使用

list類型轉換的工做原理:list(items)
  一、先造一個空列表
  二、相似調用了一個for循環,從items裏取出一個值放入空列表中,循環往復直到取乾淨爲止

1.經常使用操做+內置方法

按索引存取值

(正向存取+反向存取):便可以取也能夠改
ps:不能根據索引往列表裏新加入值

l=['a','b','c','d']
print(l[3])
print(l[-1])
l[3] = 'D'
print(l)

切片

從一個大列表中切出一個子列表(顧頭不顧尾,步長)

l=['a','b','c','d']
l1=l[1:3]
print(l1)

 len 長度

print(len(l))

成員運算in和not in

names=['mogu','nvhai','huochai',1,3,4]
print(4 in names)
print(5 not in names)

追加、插入

##append 追加值(放到末尾)    insert(索引,值)
l=['a','b','c','d']
l.append('aaa')
print(l)
l.insert(0,'B') #['B', 'a', 'b', 'c', 'd']
l.insert(0,'mogu')
print(l)

刪除

l=['a','b','mogu','d']
del l[2] # 非字符串獨有的刪除,是一種通用的刪除方式  del
print(l)
res=l.remove('alex') # 單純的刪除,沒有返回值    remove
print(l)
print(res)

#pop   從列表中拿走一個值:
#          一、刪除一個元素
#          二、將該元素當作返回值返回       
res=l.pop() # 默認從最後一個刪除
print(l)
print(res)
res=l.pop(2)
print(res)

循環

l=['a','b','c']
for item in l:  #循環取值
    print(item)

排序 sort

a=[[1,2],[3,4],[5,6],[7,8],[9,0]]
b=[8,7,9,7,9]
a.sort()
b.sort()
l1=[1,2.3,'a','a','b','a']
print(l1.count('a'))   #count  次數

l2=[4,5,6]
l1.append(l2[0])
l1.append(l2[1])
l1.append(l2[2])#append到l1的末尾

l1.extend(l2)#extend  把多個值往末尾放
print(l1)

l1=[1,2.3,'a','a','b','a']
l1.index('egon')  # index  查找   找不到會報錯
print(l1.index('a',0,3))

names=['mogu','nvhai','huochai']
names.reverse()  #reverse  將列表翻轉
print(names)

nums=[9,3,4,-1,5,100,98]
nums.sort() # 默認從小到大排序 sort
nums.sort(reverse=True) # 翻轉過來從大到小排序
print(nums)
其餘須要掌握的操做

隊列與堆棧

#隊列:先進先出
l=[]
# 入隊
l.append('first')
l.append('second')
l.append('third')

print(l)
# 出隊
print(l.pop(0))
print(l.pop(0))
print(l.pop(0))
隊列
# 堆棧:先進後出
l=[]
# 入棧
l.append('first')
l.append('second')
l.append('third')

print(l)
# 出棧
print(l.pop(-1))
print(l.pop(-1))
print(l.pop(-1))
堆棧

總結

  • 存多個值
  • 有序
  • 可變類型

4、元組使用(不可變列表)

tuple基本使用

  元組的定義:不可變的列表  ,用( )內用逗號分隔開多個任意類型的元素

t=('a',1,3.3) #t=tuple(('a',1,3.3))
print(t,type(t))     #class   tuple

1. 經常使用操做+內置方法

 1.1  按索引取值(正向取+反向取):只能取 

t1=tuple('hello') # 任意能夠被for循環的數據類型均可以被tuple轉成元組
print(t1,type(t1))

t1=('hello','world') # 任意能夠被for循環的數據類型均可以被tuple轉成元組
print(t1,type(t1))
print(t1[1])

 1.2  切片(顧頭不顧尾)

t1=(1,2,3,4,5)
print(t1[0:3])

 1.3 長度len

  與列表操做一致

 1.4 循環

  與列表操做一致

2.該類型總結

  • 存多個值
  • 有序
  • 不可變類型  
  • ps :元組可變指的元組內索引對應的內存地址不變,列表可變指的列表內索引對應的內存地址能夠改變

5、字典使用

dict基本使用

  字典用途是存多個種類不一樣的值,在{ } 內用逗號分隔開多個元素,每個元素都是key:value的形式,key應該對value有描述性的功能

  ps:注意:value能夠是任意類型,而key必須是不可變類型且惟一

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'    
}    

經常使用操做內置方法

按key存取值

可存可取

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
print(id(name_dic))
name_dic['age']=20
print(id(name_dic))
print(name_dic)

長度len

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
print(len(name_dic))

成員運算in 和not in判斷的是字典的key

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
print('age'in name_dic)

 刪除

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
res=name_dic.pop('hobby')   #刪除key對應的元素,返回value值
print(res)

鍵keys() 值values()  鍵值對 items()

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
print(name_dic.keys())
print(name_dic.values())
print(name_dic.items())

print(list(name_dic.keys()))
print(list(name_dic.values()))
print(list(name_dic.items()))

循環

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
for k in name_dic.keys():
    print(k)

for k in name_dic:
    print(k,name_dic[k])

for v in name_dic.values():
    print(v)

for k,v in name_dic.items(): #k,v=('name', 'egon')
    print(k,v)

get 取值

name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
res=name_dic.get('sex',None)
print(res)  #None

res1=name_dic.get('name',None)
print(res1)  #xiaomogu

其餘操做

# 須要掌握
name_dic={
       'name':'xiaomogu',
       'age':19,
       'hobby':'learning'
}
res=name_dic.popitem()
print(name_dic,res)  #{'name': 'xiaomogu', 'age': 19} ('hobby', 'learning')

name_dic.update({'x':1,'height':1.78}) # 老字典d沒有的則添加,有的則以新字典爲準進行修改
print(name_dic) #{'name': 'xiaomogu', 'age': 19, 'x': 1, 'height': 1.78}

總結

  • 存多個值
  • 無序
  • 可變類型

6、集合的使用

set基本使用

  集合用於:1.去重  2 .關係運算

s={1,2,1,1,1,1,1,1,1} #s=set({1,2})
print(type(s))
print(s)

1.經常使用操做+內置方法

關係運算

#關係運算
english_class={'xiaomogu','xiaohuochai','張三','張四','李五','關二爺'}
computer_class={'xiaomomo','xiaohuochai','張三','mogu','李五','xiaomogu'}
# 1.一、求既報名English又報名computer的學生有哪些->即求兩個集合體的共同部分,稱之爲交集
print(english_class & computer_class)  #{'李五', 'xiaomogu', '張三', 'xiaohuochai'}
#1.二、求只報名English,沒有報名computer的學生有哪些->即求English減去computer,稱之爲差集
print(english_class - computer_class)  #{'張四', '關二爺'}
#1.三、求只報名computer,沒有報名English的學員有哪些
print(computer_class - english_class) #{'xiaomomo', 'mogu'}
#1.4 求全部報名的學生姓名->即求兩個集合體的總和,稱之爲並集
print(english_class | computer_class) #{'xiaohuochai', 'mogu', '張四', 'xiaomogu', '張三', '李五', 'xiaomomo', '關二爺'}
#1.5 求沒有同時報名兩門課程的學生姓名->稱之爲對稱差集
print(english_class ^ computer_class)  #{'關二爺', '張四', 'xiaomomo', 'mogu'}

# 1.6 ==
s1={1,2,3}
s2={3,2,1}
print(s1 == s2)

# 注意:只有在兩個集合存在包含與被包含的關係時才能夠進行大小的比較
# 1.七、父集:>,>=
s1={1,2,3}
s2={1,2}
print(s1 > s2) # s1是s2的父集
print(s1 >= s2) # s1是s2的父集

print(s1.issuperset(s2)) #s1 >= s2

s3={1,2,3}
s4={3,4,5,6}

print(s4 >= s3)
# 1.八、子集:<,<=
print(s2.issubset(s1)) #s2 <= s1

print(len({1,2,3}))
print(1 in {1,2,3})
集合的關係運算
# 集合其餘的內置方法
s1={1,2,3,4,5}
print(id(s1))
s1.add(6)
print(s1)
print(id(s1))

s2={3,4}
s1.difference_update(s2) ## s1=s1.difference(s2) #s1=s1 - s2
print(s1)

s3={6,7}
print(s1.isdisjoint(s3))

 # 刪除
print(s1.pop()) # 隨機刪除
s1.discard(333333) # 指定元素刪除,,若是元素不存在也不報錯
s1.remove(3333) # 指定元素刪除,若是元素不存在則報錯
print(s1)

s1={1,2,3,4,5}
s1.update({3,4,5,6,7})
s1.update('hello')
print(s1)
集合的內置方法

去重

侷限性:1.不能保證原來的順序   2.不能針對可變類型去重

l=[1,1,1,1,'mogu','xiaohuochai','mogu']
s=set(l) #{1,'egon','alex'}
print(s)

l=list(s) #[]
print(l)
集合去重
# 需求:
#一、列表內的元素有可變類型
#二、去重以後要保持原來順序
info=[
    {'name':'xiaomogu','age':18},
    {'name':'momo','age':23},
    {'name':'xiaonvhai','age':17},
    {'name': '張三', 'age': 46},
    {'name':'李四','age':52},
    {'name':'xiaomogu','age':18},
]
d=[]
for dic in info:
    if dic not in d:
        d.append(dic)
info=d
print(info)
列表內可變元素去重方法

循環

s={'xiaomogu','momo','xiaonvhai','xiaohuochai'}
for item in s:
    print(item)

7、字符編碼

Python解釋器的執行原理

執行Python文件三個階段

        1.先啓動Python解釋器

        2.Python解釋器將name.py文件內容當作普通字符讀入內存

        3.Python解釋器解釋執行讀入內存的代碼,識別Python語法

notepad++讀取Python文件三個階段

        1.先啓動notepad++

        2.notepad++將name.py文件的內容當作普通字符讀入內存

        3.notepad++將讀入內存的字符打印到屏幕上

總結

    執行Python的程序前兩個階段與文本編輯器的原理同樣

    只有第三個階段纔開始識別Python語法:

    n=1000

   Python解釋器執行Python文件在第二到第三階段涉及字符的概念,會用到字符編碼

1.什麼是字符編碼

  字符編碼表就是一個存有字符與數字對應關係的表

    人類字符------->編碼 encode -------->數字

    人類字符<-------解碼decode<---------數字

  8bit = 1bytes

  ASCII : 8個二進制位(1bytes)對應一個英文字符

      A------>0001

  GBK :16二進制位(2bytes)對應中文字符,8個二進制位(1bytes)對應一個英文字符   

    a     00  ,    b   01   ,    c    10   ,   d    11

      中------>111

  Shift-JIS   : 何------>001

  Unicode:統一用2bytes對應符號

      特色:一、Unicode 數字<------->字符

         二、Unicode 數字<-------->其餘編碼的數字

      解決兩個問題:  一、兼容萬國字符

               二、與各國的編碼都有對應關係

重點

一、內存中固定使用Unicode,不能改  

二、能夠修改硬盤的編碼

        Unicode---------->編碼encode---------->GBK

        Unicode<----------解碼decode<-----------GBK

   utf-8 : 全程Unicode Transformation  Format

      1bytes表明一個英文字符

      3bytes表明一箇中文字符

結論

  但凡出現亂碼問題,必定是編碼的時候用了一套標準,而解碼的時候用了另外一套標準

  解決亂碼問題的核心: 編碼的時候用什麼編碼,解碼的時候就用什麼解碼

  Python3默認使用編碼utf-8

  Python2默認使用ASCII

  文件頭的做用:告知Python解釋器讀文件時應該用什麼編碼  

#coding=utf-8
#coding:utf-8
x=''

res1=x.encode('gbk') #unicode----編碼----->gbk
res2=x.encode('utf-8') #unicode----編碼----->gbk
print(res1,type(res1))
print(res2,type(res2))

# unicode<----編碼decode----->gbk
print(res1.decode('gbk'))
字符編碼測試

8、文件處理

1.什麼是文件:文件是操做系統爲應用程序或用戶提供的一個操做硬盤的虛擬的單位。

2.爲何要用文件:應用程序中須要常常將內存中的數據永久保存,而應用程序沒法直接操做硬盤

         只能經過操做系統提供的虛擬單位去間接地操做硬盤

3.如何用文件

Python的open操做:1.向操做系統發送打開文件的請求

           2.在應用程序拿到一個返回值,改值指向操做系統打開的文件

f=open(r'D:\a.txt',mode='r',encoding='utf-8')
# f=>應用程序中的一個值=>操做系統打開的文件a.txt=>硬盤中的一塊空間
data=f.read()
print(data)
del f
f.close() # 向操做系統發送關閉文件的請求
print(f)
f.read()

總結

  文件處理的步驟:1.打開文件  2.讀/寫文件  3 . 關閉文件

  ps:with open操做

with open(r'a.txt',mode='r',encoding='utf-8') as f,\
        open('b.txt',mode='r',encoding='utf-8') as f1:
    #文件處理的代碼塊
    pass

9、文件的打開模式

  文件的打開模式有三種

    r:只讀模式(默認)

    w:只寫模式

    a:只追加寫

  控制操做文件內容的模式有兩種(不能單獨使用,必須與上述3種其中之一連用)

    t:(默認)text文本模式,該模式下操做文件內容的單位都是字符串,該模式只適用於文本文件  ps:該模式必須指定encoding='某種字符編碼'

    b:bytes二進制模式,該模式下操做文件內容的單位都是bytes,該模式適用於全部類型的文件

一、r模式:只讀(默認)

  文件不存在則報錯;文件存在,而且文件指針調到文件開頭

with open('a.txt',mode='rt',encoding='utf-8') as f:
    data1=f.read()
    print(type(data1))
    print('第一次:',data1) #第一次所有讀取完畢
    data2=f.read()
    print('第二次',data2)  #第二次爲空
with open('a.txt', mode='rt', encoding='utf-8') as f:
    line1=f.readline() #readline 一次只讀取一行,指針跳到第二行開頭
    print(line1,end='')
    print('====>')
    line2 = f.readline()#readline 一次只讀取一行,指針跳到第二行開頭
    print(line2, end='')


with open('a.txt', mode='rt', encoding='utf-8') as f:
    l=f.readlines()#一次性所有讀取,包括換行符\n
    for i in l:
        print(i,end='')
    print(l,type(l))

二、w模式:只寫模式

  文件不存在則建立空文檔,而且文件指針跳到文件的開頭

  文件存在,會將內容清空,而且文件指針跳到文件的開頭

  ps:若是每次都是從新打開文件,那麼文件的內容總會清空,指針跳到開頭

    若是在打開文件不關閉的清空下,連續的寫入,本次寫入會基於上一次指針所在位置日後繼續寫

with open('c.txt',mode='wt',encoding='utf-8') as f:
#不關閉文件的清空下連續的寫入
    f.write('hello\n')
    f.write('小蘑菇\n')
    l=['123\n','啦啦啦\n','賣女孩的小火柴\n']
    for line in l:
        f.write(line)
    f.writelines(l)

三、a模式:只追加寫入

  文件不存在則建立一個空文檔,而且文件指針跳到文件的末尾

  文件存在,也會將文件指針跳到文件的末尾

x=str(100-50)
with open('a.txt',mode='at',encoding='utf-8') as f:
    print(f.readable())
    print(f.writable())
    # f.read() 沒法讀取
    f.write('100')
    f.writelines([x,'\n'])
#讀取文件的內容轉換類型進行數學運算
with open('a.txt',mode='rt',encoding='utf-8') as f1:
    res=f1.readline()
    res2=f1.readline()
    print(res)
    print(res2)
    res3=int(res)+int(res2)
    print(res3)

四、b模式

bytes二進制模式,該模式下操做文件的內容的單位都是bytes,該模式適用於全部的文件類型

  ps:必定不能指定encoding參數

with open('1.mp4',mode='rb') as f:
    data=f.readline()
    print(data,type(data))
with open('d.txt',mode='rb') as f:
    data=f.read()
    # print(data,type(data))  #二進制模式
    res=data.decode('utf-8')  #讀取需指定解碼的編碼類型
    print(res)
# 遍歷文件內容的方式
with  open('d.txt',mode='rt',encoding='utf-8') as f:
    for line in f: #line='bbb\n'
        print(line,end='')
遍歷文件內容的方式

10、文件內指針的移動

  文件內指針的操做:f.seek

   第一個參數:控制移動的字節數

   第二個參數:控制移動的參照物,值能夠爲0(t、b模式均可以用)、一、2(1(文件的中間)2(文件的末尾)只能在b模式下使用)

with open('e.txt',mode='rt',encoding='utf-8') as f:
    f.seek(6,0) # 單位是字節
    print(f.read())  #移動6個字節後讀取
    f.read()
    f.seek(0,0)  #又將指針移動到了開頭
    print('第二次',f.read())
#read的n在t模式下表明的是字符個數
#read的n在b模式下表明的是字節個數

with open('e.txt',mode='rb') as f:
    data=f.read(3) #讀取3個字節,即爲一箇中文字符
    print(data.decode('utf-8'))

11、文件的修改

1、文本編輯器修改文件的原理

      一、先將文件內容所有讀入內存

      二、在內存中修改完畢

      三、將修改的結果覆蓋寫回硬盤

      優勢:在修改期間硬盤上同一時刻只有一份數據

      缺點:佔用內存太高

with open('db.txt',mode='rt',encoding='utf-8') as f:
    data=f.read()
    new_data=data.replace('蘑菇','小蘑菇') #替換
    print(new_data)

with open('db.txt',mode='wt',encoding='utf-8') as f:
    f.write(new_data)

一行行的讀,一行行的改

    1.以讀的模式打開源文件,以寫的模式打開一個臨時文件

    2.而後用for循環讀取原文件一行行的內容,每讀一行則修改一行,將修改的結果寫入臨時文件,直到把源文件都遍歷完

    3.刪除原文件,將臨時文件重命名爲原文件名

    優勢:同一時刻在內存中只存在文件的一行內容

    缺點:在修改期間硬盤上同一份數據會有兩份

import os

with open('db.txt',mode='rt',encoding='utf-8') as src_f,\
        open('.db.txt.swap',mode='wt',encoding='utf-8') as temp_f:
    for line in src_f:
        if '要修改的內容' in line:
            line=line.replace('同上內容','小蘑菇')
        temp_f.write(line)

os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')
# 此操做用於刪除特定內容所在的行
with open('db.txt','rt',encoding='utf-8')as f:
    lines=f.readlines()
with open('db.txt', 'wt', encoding='utf-8')as f1:
    for line in lines:
        if 'dsb' in line:  #若是內容在這行  將刪除這行,別的行不動
            continue
        f1.write(line)
刪除指定內容的行

練習

打印金字塔

#              #max_level=5
#     *        #current_level=1,空格數=4,*號數=1
#    ***       #current_level=2,空格數=3,*號數=3
#   *****      #current_level=3,空格數=2,*號數=5
#  *******     #current_level=4,空格數=1,*號數=7
# *********    #current_level=5,空格數=0,*號數=9

#數學表達式
# 空格數=max_level-current_level
# *號數=2*current_level-1

max_level=int(input('數字: '))
for current_level in range(1,max_level+1):
    for i in range(max_level-current_level):
        print(' ',end='')
    for l in range(2*current_level-1):
        print('*',end='')
    print()
打印金字塔

三級菜單

#要求:
# 打印省、市、縣三級菜單
# 可返回上一級
# 可隨時退出程序
menu = {
    '北京':{
        '海淀':{
            '五道口':{
                'soho':{},
                '網易':{},
                'google':{}
            },
            '中關村':{
                '愛奇藝':{},
                '汽車之家':{},
                'youku':{},
            },
            '上地':{
                '百度':{},
            },
        },
        '昌平':{
            '沙河':{
                '老男孩':{},
                '北航':{},
            },
            '天通苑':{},
            '回龍觀':{},
        },
        '朝陽':{},
        '東城':{},
    },
    '上海':{
        '閔行':{
            "人民廣場":{
                '炸雞店':{}
            }
        },
        '閘北':{
            '火車站':{
                '攜程':{}
            }
        },
        '浦東':{},
    },
    '山東':{},

}

tag=True
while tag:#一級菜單
    menu1=menu
    for name in menu1:#打印第一層
        print(name)
    diyi=input('第一層>>>: ').strip()
    if  diyi=='q':#輸入q則退出
        tag=False
    if diyi not in menu1: continue

    while tag:#二級菜單
        menu2=menu1[diyi]#menu[diyi]
        for name in menu2:#打印第二層
            print(name)
        dier=input('第二層>>>: ').strip()
        if dier == 'b': break#輸入b則返回上一層
        if dier == 'q':#輸入q則退出
            tag=False
        if dier not in menu2: continue

        while tag:#三級菜單
            menu3=menu2[dier]#menu[diyi][dier]
            for name in menu3:#打印第三層
                print(name)
            disan=input('第三層>>>: ').strip()
            if disan == 'b': break#輸入b則返回上一層
            if disan == 'q':#輸入q則退出
                tag=False
            if disan not in menu3: continue

            while tag:#四級菜單
                menu4=menu3[disan]#menu[diyi][dier][disan]
                for name in menu4:#打印第四層
                    print(name)
                disi=input('第四層>>>: ').strip()
                if disi == 'b': break#輸入b則返回上一層
                if disi == 'q':#輸入q則退出
                    tag = False
                if disi not in menu4: continue
三級菜單

實現簡單購物車

#用戶名和密碼存放於文件中,格式爲:
#啓動程序後,先登陸,登陸成功則讓用戶輸入工資,而後打印商品列表,失敗則從新登陸,超過三次則退出程序
        #容許用戶根據商品編號購買商品
          # 用戶選擇商品後,檢測餘額是否夠,夠就直接扣款,不夠就提醒
          # 可隨時退出,退出時,打印已購買商品和餘額

#用戶列表
mogu|123

product_list = {'1':['Iphone7',5800],
                '2':['Coffee',30],
                '3':['疙瘩湯',10],
                '4':['Python Book',99],
                '5':['Bike',199],
                '6':['ViVo X9',2499]}


d=product_list
#前期定義
tag=True
shopping=[]
with open('用戶列表',mode='rt',encoding='utf-8')as user:#打開用戶列表準備讀取
    res=user.read().split('|')#讀取按照'|'進行切分
    name=res[0]#讀0號索引字符,賦值給name
    pwd=res[1]#讀1號索引字符,賦值給pwd
n=1
while tag:#第一層循環開始
    if n==3:#若是錯誤3次則退出
        tag=False
    inp_name=input('輸入您的用戶名:').strip()
    if not inp_name or inp_name not in name:#判斷輸入字符與name的關係
        print('用戶名不存在!')
        continue
    inp_pwd=input('輸入您的密碼:').strip()
    if  inp_pwd==pwd:#判斷輸入字符與pwd的關係
        print('登陸成功!!!')
    else:
        print('您輸入的密碼有誤!')
        n+=1
        continue
    while tag:#第二層循環開始
        wage=input('請輸入您的工資:').strip()#第一次的金額
        if not wage.isdigit():#判斷輸入的是不是數字
            print('請輸入數字')
            continue
        with open('餘額', mode='wt', encoding='utf-8') as gongzi:#第一次新建文件‘餘額’
            gongzi.write(wage)#寫入以前輸入的wage
        for k, v in d.items():  # k,v=('編號', '子列表')
            print(k,'',v)#循環打印字典的k,v
        while tag:#第三層循環開始
            print('q:退出')
            choice = input('購買商品:').strip()
            if choice=='q':#退出機制
                tag=False
                break
            if not choice or choice not in d:#判斷輸入字符與商品列表關係
                print('輸入錯誤,請從新輸入!')
                continue
            count = input('購買數量:').strip()
            if not count.isdigit():continue#判斷count是否爲數字

            wage1=int(d[choice][1])*int(count)#計算選擇的商品乘數量後的價格

            with open('餘額', mode='rt', encoding='utf-8') as f1:#選擇商品後再次讀取餘額
                wage2=int(f1.read())
            if wage1 > wage2:#用戶選擇商品後,檢測餘額(做比較),夠就(餘額-商品金額)不夠就提醒
                print('餘額不足!')
                continue
            shopping.append(('商品',d[choice],'數量',count))
            #選擇一次商品計算一次(工資減商品金額=餘額   存入文件)
            with open('餘額', mode='rt', encoding='utf-8') as balance:#第二次讀取餘額文件
                yue=balance.read()#讀取餘額賦值給yue
            with open('餘額',mode='wt',encoding='utf-8') as balance1:#第二次寫入計算結果至餘額文件
                balance1.write(str(int(yue)-wage1))

with open('餘額', mode='rt', encoding='utf-8') as ff:#第二次讀取計算後的餘額賦值給rse
    rse=ff.read()
    print('已購買',shopping,'餘額',rse)
View Code
相關文章
相關標籤/搜索