Python之路【第二篇】:Python基础2之数据类型
一、字符串操作
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # 字符基础方法 name = 'CoCoa-Z' print(name.capitalize()) # 首字母大写,结果:Cocoa-z print(name.casefold()) # 大写全部变小写,结果:cocoa-z print(name.swapcase()) # 大小写互换,结果:cOcOA-z print(name.center(20,'-')) # 输出 ------CoCoa-Z------- print(name.count('Co')) # 统计'Co'出现的次数,结果:2 print(name.endswith('-Z')) # 判断字符串是否以-Z结尾,结果:True print(name.find('a')) # 查找a,找到返回其索引,找不到返回-1,结果:4 print("Alex\tLi".expandtabs(10)) # 输出'Alex Li', 将\t转换成多长的空格 print(name.index('a')) # 返回a第一次出现所在字符串的索引 # 字符串格式化 msg = 'my name is {0}, and age is {1}' print(msg.format('Alex','18')) # my name is Alex, and age is 18 msg = 'my name is {name}, and age is {age}' print(msg.format(age=20,name='Alex')) # my name is Alex, and age is 18 msg = 'my name is {name}, and age is {age}' print(msg.format_map({'name':'alex','age':22})) # my name is Alex, and age is 18 # 字符串格式化输出, strip()去除用户输入的前后的空白字符 name = input('plases input your name:').strip() age = input('plases input your age:') job = input('plases input your job:').strip() salary = input('plases input your salary:') str = ''' Personal infomation of %s: Name: %s Age : %s Job : %s Salary: %s --------------------------------- ''' %(name,name,age,job,salary) print(str)
字符串拼接中万恶的'+'号:
# 通过‘+’号字符串进行拼接内存的保持n+1份(n为+号出现的次数) print('abc'+'cde'+'efg') # abc # abccde # abccdeefg # 使用占位符%s等进行字符串拼接内存只会存2份数据 print('abc%s%s' %('cde','efg')) # abc # abccdeefg
将列表按指定的分隔符组合成字符串:
name_list = ['A','l','e','x','s','b'] name_str = '-'.join(name_list) print(name_str) #A-l-e-x-s-b
二. 列表操作
# 定义列表 names = ['Alex',"Tenglan",'Eric'] # 通过下标访问列表中的元素,下标从0开始计数 print(names[0]) print(names[1]) print(names[2]) # 还可以倒着取 print(names[-1]) print(names[-2]) # 切片:取多个元素 names = ["Alex","Tenglan","Eric","Rain","Tom","Amy"] names[1:4] # 取下标1至下标4之间的数字,包括1,不包括4 ['Tenglan', 'Eric', 'Rain'] names[1:-1] # 取下标1至-1的值,不包括-1 ['Tenglan', 'Eric', 'Rain', 'Tom'] names[0:3] # 取列表中钱3个元素 ['Alex', 'Tenglan', 'Eric'] names[:3] # 如果是从头开始取,0可以忽略,跟上句效果一样 ['Alex', 'Tenglan', 'Eric'] names[3:] # 如果想取最后一个,必须不能写-1,只能这么写 ['Rain', 'Tom', 'Amy'] names[3:-1] # 这样-1就不会被包含了 ['Rain', 'Tom'] names[0::2] # 后面的2是代表,每隔一个元素,就取一个 ['Alex', 'Eric', 'Tom'] names[::2] # 和上句效果一样 ['Alex', 'Eric', 'Tom'] # 追加 names.append('new_name') ['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy', 'new_name'] # 插入 names.insert(2,'插入到所有为2的位置') ['Alex', 'Tenglan', '插入到所有为2的位置', 'Eric', 'Rain', 'Tom', 'Amy', 'new_name'] # 修改 names[2] = '更新' ['Alex', 'Tenglan', '更新', 'Eric', 'Rain', 'Tom', 'Amy', 'new_name'] # 根据元素的值删除指定元素 names.remove('更新') ['Alex', 'Tenglan', 'Eric', 'Rain', 'Tom', 'Amy', 'new_name'] # 根据元素的索引删除指定元素,默认删除列表最后一个值 names.pop(1) ['Alex', 'Eric', 'Rain', 'Tom', 'Amy', 'new_name'] # 扩展 a = ['a','b','c'] b = [1, 2, 3] a.extend(b) ['a', 'b', 'c', 1, 2, 3] # 拷贝 names = ['Alex', 'Tenglan', 'Rain', 'Tom', 'Amy', 1, 2, 3] names_copy = names.copy() ['Alex', 'Tenglan', 'Rain', 'Tom', 'Amy', 1, 2, 3] # 排序 names =[19, 22, 8, 88, 65, 21] names.sort() [8, 19, 21, 22, 65, 88] # 翻转 names.reverse() [88, 65, 22, 21, 19, 8] # 统计: 统计Amy在列表中出现的次数 names = ['Alex', 'Tenglan', 'Amy', 'Tom', 'Amy', 1, 2, 3] print(names.count('Amy')) # 获取下标 names = ['Alex', 'Tenglan', 'Amy', 'Tom', 'Amy', 1, 2, 3] print(names.index("Amy")) # 只返回找到的第一个下标
二. 元组操作
元组其实跟列表差不多,也是存一组数,只不是它一旦创建,便不能再修改,所以又叫只读列表
语法:
names = ("alex","jack","eric")
它只有2个方法,一个是count,一个是index。
注意:元组的元素是不能修改的,但是元组中元素中的元素是可以修改的。
#!/usr/bin/env python3 tup = ('a','b',{'name':'cocoa-z'}) # 元组的元素是不能修改的,修改后会报一下错误. tup[2] = 'c' #TypeError: 'tuple' object does not support item assignment # 元组的元素中的元素是可以修改. tup[2]['name'] = 'cocoa-f' #('a', 'b', {'name': 'cocoa-f'})
三、 字典操作
字典一种key - value 的数据类型,使用就像我们上学用的字典,通过笔划、字母来查对应页的详细内容。
# 创建一个字典 stu_info = { 'stu1101': "TengLan Wu", 'stu1102': "LongZe Luola", 'stu1103': "XiaoZe Maliya", } # 增加 stu_info['stu1104'] = "Binbin Fan" {'stu1101': 'TengLan Wu', 'stu1102': 'LongZe Luola', 'stu1103': 'XiaoZe Maliya', 'stu1104': 'Binbin Fan'} # 修改 stu_info['stu1104'] = "Binbin Li" {'stu1101': 'TengLan Wu', 'stu1102': 'LongZe Luola', 'stu1103': 'XiaoZe Maliya', 'stu1104': 'Binbin Li'} # 删除 stu_info.pop('stu1104') # 根据key删除某个元素 {'stu1103': 'XiaoZe Maliya', 'stu1101': 'TengLan Wu', 'stu1102': 'LongZe Luola'} stu_info.popitem() # 随机删除某个元素 {'stu1101': 'TengLan Wu', 'stu1103': 'XiaoZe Maliya'} # 查找 stu_info = {'stu1102': 'LongZe Luola', 'stu1103': 'XiaoZe Maliya'} "stu1102" in stu_info # 标准用法 stu_info.get("stu1102") # 获取 stu_info["stu1102"] # 同上 # 结果集 stu_info = {'stu1102': 'LongZe Luola', 'stu1103': 'XiaoZe Maliya'} print(stu_info.keys()) (['stu1102', 'stu1103']) print(stu_info.values()) (['LongZe Luola', 'XiaoZe Maliya']) print(stu_info.items()) ([('stu1102', 'LongZe Luola'), ('stu1103', 'XiaoZe Maliya')]) # 扩展: 将两个字典中不相同的内容合并成一个 stu_info = {'stu1102': 'LongZe Luola', 'stu1103': 'XiaoZe Maliya'} stu_info2 = {'stu1104': 'Binbin Li', 'stu1103':'XiaoZe Maliya'} stu_info.update(stu_info2) print(stu_info) {'stu1103': 'XiaoZe Maliya', 'stu1104': 'Binbin Li', 'stu1102': 'LongZe Luola'} # 循环dict #方法1 for key in stu_info: print(key,info[key]) #方法2 for k,v in stu_info.items(): #会先把dict转成list,数据里大时莫用 print(k,v)
get的特殊用法, 如果key不存在,则返回默认值None,也可以当key不存在时自己设置默认值.
dic = {'key1':'val1','key2':'val2'} print(dic['key1']) print(dic['key2']) #print(dic['key3']) # 此处会报告异常,KeyError: 'key3' print(dic.get('key1')) print(dic.get('key2')) print(dic.get('key3')) # 此处会输出key3的默认值None print(dic.get('key3','default')) # 此处会输出key3的设置的默认值default
四、 集合操作
集合是一个无序的,不重复的数据组合,它的主要作用如下:
- 去重,把一个列表变成集合,就自动去重了
- 关系测试,测试两组数据之前的交集、差集、并集等关系
1、基本操作
chs = set("Hello") # 创建一个唯一字符的集合 {'o', 'H', 'l', 'e'} chs.add('s') # 添加一项 {'H', 'l', 's', 'e', 'o'} chs.update(['a','b','c']) # 添加多项 {'a', 's', 'H', 'l', 'e', 'o', 'b', 'c'} chs.remove('s') # 删除一项 {'H', 'e', 'a', 'c', 'b', 'o', 'l'}
# difference:找出两个集合中的不同的元素并创建一个集合返回 set1 = set(['alex','eric','tony','alex']) set2 = set(['alex','eric']) set3 = set1.difference(set2) print(set3) # difference_update:找出两个集合中的不同的元素并修改原来集合中的内容 set1 = set(['alex','eric','tony','alex']) set2 = set(['alex','eric']) set1.difference_update(set2) print(set1) # pop: 删除集合中的最后一个元素并返回该元素 set_name = {'Alex','Eric','Tony'} name = set_name.pop() print(name) # remove: 删除集合中指定的元素 set_name = {'Alex','Eric','Tony'} set_name.remove('Eric') print(set_name)
2、集合运算
x = {'a','b','c','d'} y = {'c','d','e','f'} x & y # 求交集 x.intersection(y) {'d', 'c'} x | y # 求并集 x.union(y) {'a', 'c', 'b', 'f', 'd', 'e'} x ^ y # 求对称差集 x.symmetric_difference(y) {'e', 'f', 'a', 'b'} x - y # 求差集 x.difference(y) {'a', 'b'} y - x # 求差集 y.difference(x) {'e', 'f'} x.issubset(y) # x是y的子集 x.issuperset(y) # x是否包含y
练习:寻找差异
# 数据库中原有 old_dict = { "#1":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 }, "#2":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 }, "#3":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 } } # cmdb 新汇报的数据 new_dict = { "#1":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 800 }, "#3":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 }, "#4":{ 'hostname':'c1', 'cpu_count': 2, 'mem_capicity': 80 } } old_set = set(old_dict.keys()) new_set = set(new_dict.keys()) update_set = old_set & new_set delete_set = old_set ^ update_set insert_set = new_set ^ update_set print(update_set,delete_set,insert_set)
五、文件操作
对文件操作流程
- 打开文件,得到文件句柄并赋值给一个变量
- 通过句柄对文件进行操作
- 关闭文件
# 以只读的方式打开文件并处理 [这样处理后没行就是一个列表]
f = open("passwd","r")
for line in f.readlines():
line = line.strip("\n").split(":")
print(line)
f.close()
# 以只写的方式打开文件,在写入新的内容后原来的数据将会会覆盖
f2 = open("passwd","w")
f2.write("new line\n")
f2.flush()
f2.close()
# 以追加的方式打开文件,在写入新的内容后原来的数据将会保留
f3 = open("passwd","a")
f3.write("Second line\n")
f3.write("Thrid line\n")
f3.flush()
打开文件的模式有:
- r, 只读模式(默认)
- w, 只写模式 【不可读;不存在则创建;存在则删除内容;】
- a, 追加模式 【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+,可读写文件。【可读;可写;可追加】
- w+,写读
- a+,同a
为了避免打开文件后忘记关闭,可以通过with语句管理上下文,即:
with open('log','r') as f: ...
六、collection类
Counter是一个简单的计数器,例如,统计字符出现的个数:
import collections c_str = collections.Counter('programming') print(c_str) c_list = collections.Counter(['avi','abc','act','avi','act','trp']) print(c_list) #结果 Counter({'g': 2, 'm': 2, 'r': 2, 'p': 1, 'n': 1, 'a': 1, 'o': 1, 'i': 1}) Counter({'act': 2, 'avi': 2, 'trp': 1, 'abc': 1})
OrderdDict是对字典类型的补充,他记住了字典元素添加的顺序:
from collections import OrderedDict # 普通的字典中的数据是无序的 dict_test = {'jen':'python','sarah':'c','edward':'ruby','phil':'python'} for key in dict_test: print(key+ "'s favorite language is " + dict_test[key] + ".") # orderdDict字典中的数据是有序的,按插入的顺序进行排序,原理为这个字典在内部维护了一个key的列表 favorite_languages = OrderedDict() favorite_languages['jen'] = 'python' favorite_languages['sarah'] = 'c' favorite_languages['edward'] = 'ruby' favorite_languages['phil'] = 'python' for name,language in favorite_languages.items(): print(name.title() + "'s favorite language is " + language.title() + ".") # 结果 sarah's favorite language is c. edward's favorite language is ruby. jen's favorite language is python. phil's favorite language is python. -------------------------------------- Jen's favorite language is Python. Sarah's favorite language is C. Edward's favorite language is Ruby. Phil's favorite language is Python.
defaultdict是对字典的类型的补充,他默认给字典的值设置了一个类型:
有如下值集合 [11,22,33,44,55,66,77,88,99...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。
即: {'k1': 大于66 , 'k2': 小于66}
from collections import defaultdict num_lst = [11,22,33,44,55,66,77,88,99] default_dict_test = defaultdict(list) for num in num_lst: if num < 66: default_dict_test['k1'].append(num) else: default_dict_test['k2'].append(num) print(default_dict_test)
看出神奇的地方了么?我们可以不需要在空字典中指定value的值,直接执行append,就可以向字典中插入值了,
就是因为我们使用defauldict(list)方式定义了一个value值默认为list的字典。
否则我们就要这么写才行:
num_list = [11,22,33,44,55,66,77,88,99,100] num_dict = {'key1':[],'key2':[]} for num in num_list: if num > 55: num_dict['key1'].append(num) else: num_dict['key2'].append(num) print(num_dict)
Eric的方法:
num_lst = [11,22,33,44,55,66,77,88,99,90] dic = {} for num in num_lst: if num < 66: if 'k1'in dic.keys(): dic['k1'].append(num) else: dic['k1'] = [num,] else: if 'k2'in dic.keys(): dic['k2'].append(num) else: dic['k2'] = [num,] print(dic)
可命名元组:
Mytupleclass = collections.namedtuple('Mytupleclass',['x','y','z']) mytuplecclass = Mytupleclass(11,22,33) print(mytuplecclass.x) print(mytuplecclass.y) print(mytuplecclass.z)
双向队列:collections.deque()
d = collections.deque() d.append('11') d.append('22') d.appendleft('00') print(d) # deque(['00', '11', '22']) d.extend(['xx','yy','zz']) d.extendleft(['aa','bb','cc']) print(d) # deque(['cc', 'bb', 'aa', '00', '11', '22', 'xx', 'yy', 'zz']) d.pop() d.popleft() print(d) # deque(['bb', 'aa', '00', '11', '22', 'xx', 'yy']) d.insert(0,'aaa') print(d) # deque(['aaa', 'bb', 'aa', '00', '11', '22', 'xx', 'yy']) d.rotate(3) print(d) # deque(['22', 'xx', 'yy', 'aaa', 'bb', 'aa', '00', '11'])
单项队列:queue.Queue() 先进先出
import queue q = queue.Queue() q.put('aa') q.put('bb') q.put('cc') print(q.get())
七、深浅copy
#!/usr/bin/evn python3 import copy """ 字符串和数字中的赋值以及深浅copy """ #str1 = 'abc' str1 = 123 str2 = str1 print(id(str1) == id(str2)) # True str3 = copy.copy(str1) print(id(str1) == id(str3)) # True str4 = copy.deepcopy(str1) print(id(str1) == id(str4)) # True print('-------------') """ 其它类型中的赋值以及深浅copy """ dict1 = {'key1':'abc','key2':123,'key3':['Alex',456]} dict2 = dict1 print(id(dict1) == id(dict2)) # True dict3 = copy.copy(dict1) print(id(dict1) == id(dict3)) # False print(id(dict1['key3']) == id(dict3['key3'])) # True dict4 = copy.deepcopy(dict1) print(id(dict1) == id(dict4)) # False print(id(dict1['key3']) == id(dict4['key3'])) # False """ 深浅copy的应用: 以下数据模板一直在使用,老机器都使用此模板,但是新机器的性能不同, 需要使用新的模板,此时copy数据的时候就要使用deepcopy了。 """ dict_old = { 'CPU':[80,], 'MEM':[80,], 'DISK':[80,] } dict_new = copy.copy(dict_old) dict_new['MEM'][0] = 50 print(dict_old) print(dict_new) # 这里的数据(dict_new和dict_old)都改变了,但是老的数据模板还在使用,这里就必须使用deepcopy dict_new = copy.deepcopy(dict_old) dict_new['MEM'][0] = 60 print(dict_old) print(dict_new)
八、练习
程序1:购物车程序
需求:
- 启动程序后,让用户输入工资,然后打印商品列表
- 允许用户根据商品编号购买商品
- 用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
#!/usr/bin/env python # -*- coding: utf-8 -*- #定义一个商品列表 goods_list = [ ('Iphone',5800), ('Bike',800), ('Book',45), ('Coffee',35), ('Solo 2 Beats',1590), ('MX4',1999), ('quit',0) ] #定义购物车列表 buy_list = [] def show_all_goods(): """ 显示所有的商品 :return: None """ for item, goods in enumerate(goods_list,1): print(item, goods[0], goods[1]) def get_choise_goods_info(choise_goods_item): """ 获取用户选择的商品信息 :param choise_goods_item: 选择商品的编号 :return: 商品的名称,商品的编号 """ choise_goods_name = goods_list[choise_goods_item-1][0] choise_goods_price = goods_list[choise_goods_item-1][1] return choise_goods_name, choise_goods_price def account_balance(choise_goods_price, balance): """ :param choise_goods_price: 选择的商品价格 :param budget: 余额 :return: 当前余额大于当前商品价格返回,减去商品价格的余额;反之返回-1 """ if balance > choise_goods_price: balance -= choise_goods_price return balance else: return -1 def append_to_buy_list(choise_goods_name): """ 将选择的商品加入购物车 :param choise_goods_name: 选择商品的名字 :return:None """ buy_list.append(choise_goods_name) def show_buy_goods(buy_list): """ 显示已经购买的商品 :param buy_list:购买商品列表 :return: None """ for item, goods in enumerate(buy_list,1): print(item, goods) #输入预算 budget = int(input("please input your budget:").strip()) balance = budget while True: # 列出所有的商品 print('本店商品:') show_all_goods() # 根据用户输入的商品编号获取商品信息 choise_goods_item = int(input('请选择您需要的商品编号:').strip()) choise_goods_name, choise_goods_price = get_choise_goods_info(choise_goods_item) print('------',choise_goods_name,'------') # 将商品加入购物车并对账户进行操作 balance = account_balance(choise_goods_price, balance) if balance != -1: # 将用户的商品信息加入到购物车 append_to_buy_list(choise_goods_name) print('当前账户余额为:',balance) else: # 余额不足,退出程序 print('余额不足!') break # 显示已经购买的商品 print('已经购买了以下商品:') show_buy_goods(buy_list)
程序2: 三级菜单
要求:
- 打印省、市、县三级菜单
- 可返回上一级
- 可随时退出程序
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import sys # 定义省市县 menu_dict = { '安徽省':{'池州市':['东至县','青阳县','石台县'], '合肥市':['蜀山区','经开区','政务区'], '安庆市':['宿松县','怀宁县','枞阳县']}, '江西省':{'九江市':['湖口县','彭泽县','修水县'], '南昌市':['东湖区','西湖区','湾里区'], '赣州市':['安远县','崇义县','大余县']} } def show_province(): """ 显示所有的省 :return: """ for province in menu_dict.keys(): print(province) def is_province(input_province): """ 判断输入是否是一个省 :param input_province: 输入的省 :return: """ if input_province in menu_dict.keys(): return True else: return False def show_city(province): """ 显示当前省下面所有的市 :param input_province: 输入的省 :return: """ for city in menu_dict[province].keys(): print(city) def is_city(input_province,input_city): """ 判断输入是否是一个市 :param input_province: 输入的省 :param input_city: 输入的市 :return: """ if input_city in menu_dict[input_province].keys(): return True else: return False def show_county(province, city): """ 显示当前市下面所有的县 :param province: 输入的省 :param city: 输入的市 :return: """ for county in menu_dict[province][city]: print(county) def is_county(input_province,input_city,input_county): """ 判断输入是否是一个县 :param input_province: 输入的省 :param input_city: 输入的市 :param input_county: 输入的县 :return: """ if input_county in menu_dict[input_province][input_city]: return True else: return False while True: show_province() input_province = input('请选择你所在的省(输入quit返回上级菜单,输入exit退出程序.):') if input_province == 'quit': continue if input_province == 'exit': sys.exit() if not is_province(input_province): print('您所输入的省不存在,请重新输入:') continue while True: show_city(input_province) input_city = input('请选择你所在的市(输入quit返回上级菜单,输入exit退出程序.):') if input_city == 'quit': break if input_city == 'exit': sys.exit() if not is_city(input_province,input_city): print('您所输入的市不存在,请重新输入:') continue while True: show_county(input_province, input_city) input_county = input('请选择你所在的县(输入quit返回上级菜单,输入exit退出程序.):') if input_county == 'quit': break if input_county == 'exit': sys.exit() if not is_county(input_province,input_city,input_county): print('您所输入的县不存在,请重新输入:') continue print('您目前居住在{0},{1},{2}'.format(input_province, input_city, input_county)) sys.exit()
程序3: 用户登录接口
要求:
- 用户名密码输入正确后提示登录成功
- 登录错误三次后锁定用
#!/usr/bin/python # -*- coding: UTF-8 -*- import sys # 检查用户名和密码是否正确 def user_isexist(input_username, input_password): user_list = open('userList.txt','r') status = True for line in user_list.readlines(): user = line.strip("\n").split() username = user[0] password = user[1] if input_username == username and input_password == password: status = True break else: status = False user_list.close() return status # 判断用户是否已经被锁定 def user_islocked(input_username): dropuser_list = open('dropUser.txt', 'r') status = True for line in dropuser_list.readlines(): drop_username = line.strip("\n") if drop_username == input_username: status = True break else: status = False dropuser_list.close() return status # 如果用户密码输入错误三次,锁定用户 def user_locked(input_username): dropuser_list = open('dropUser.txt', 'a') dropuser_list.write(input_username) dropuser_list.write('\n') dropuser_list.close() # Main input_username = input('Please input you username:') count = 0 while count < 3: # 如果用户没有被锁定 if not user_islocked(input_username): input_password = input('Please input you password:') # 如果用户存在 if user_isexist(input_username, input_password): print('welcome ...') sys.exit() # 如果用户不存在 else: print('You input username or password is error!') # 如果用户已经被锁定 else: print("You account has been locked,please contact the administrator!") sys.exit() count += 1 # 输入错误三次,锁定用户 if count == 3: user_locked(input_username) print('You account has been locked!')