day2 列表 元组 字符串 字典
一、列表、元祖
1、list为是有序的,因此又下标,可以多多层嵌套
tuple和list差不多,但是tuple一旦创建第一级就不能修改,比如其中一个元素为list,则改list可以被修改
2、list、tuple方法
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen import copy animal = ['dog', 'cat', 'tiger', 'fish', 'fish', 'lion', 'dog'] vegetables = ['potato', 'tomato', 'bean'] tuple_test = (1, 2, [1, 3, 6]) tuple_test[2][2] = 11 # 元祖不能修改是指第一级 但是里面的list可以被修改 print(tuple_test) for i, v in enumerate(animal): # enumerate同时列出数据和数据下标 print(i, v) print(animal.count('dog')) # 统计出现的次数 animal.append('horse') # 列表后面追加 something = animal.copy() # 只copy第一级,如果第二级是list则只是引用,修改其中一个第二级的值两个都会修改 something2 = copy.copy(animal) # copy 和 list.copy是一样的 something3 = copy.deepcopy(animal) # 完全复制一份,不引用 something.extend(vegetables) # 合并两个list print(something) print(something.index('tomato')) # 列出tomato的索引 del something[-3] # 通用删除法 something.pop(-3) # 删除索引为-3的对象,默认最后一个 something.append('cabbage') print(something) something.remove('dog') # 删除指定元素 print(something) something.insert(1, 'soy') # 在指定位置插入元素 print(something) something.reverse() # 反转列表的顺序 print(something) something.sort() # 对列表进行排序,默认ASCII进行排序 key参数可以指定函数返回的值来排序 print(something) print(something[0:4]) # 切片 print(something[-3:-1]) # 如果是负数下标,但是还是按从左往右切片 print(something[0:4:2]) # 取0到4 每隔两个取一个
二、字符串
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen name = ' my name is glen HHH,\t I am {age} \r\n years old, hello everyone ! \n' print(name.count('y')) # 统计在字符中出现的次数 print(name.capitalize()) # 首字母大写 print(name.casefold()) # 大写全变小写 print(name.center(50, '-')) # 一共输出50个字符,如果不够就在两边补足‘-’,str放中间 name_b_gbk = name.encode(encoding='gbk') # 将str编码为bytes的二进制形式,解码也需要对应的字符集,默认utf-8 print(name_b_gbk) print(name_b_gbk.decode(encoding='gbk')) # 需要对应的解码字符集 print(name.endswith('!')) # 判断已什么字符结尾,返回True或者False print(name.expandtabs(20)) # 将 table=制表符=\t 转换为多长的空格 print(name.format(age=26)) # {}中预先设置的字符转换为变量值 print(name.format_map({'age': '20'})) # 和format类似,可以直接使用字典进行赋值 print(name.find('I')) # 从左到右查询,返回第一个匹配的字符下标 ASCII 表区分大小写 print(name.rfind('l')) # 从右往左查询,返回第一个匹配字符的下表 print(name.index('i')) # 返回字符i所在的索引 number = '123' print(number.isalnum()) # 判断字符串里面的每个字符是否为纯数字 小数点为字符,返回True or False alpha = 'Abc' print(alpha.isalpha()) # 判断是否为纯字母, 返回True or False print(name.isdecimal()) # 不常用,检查字符串是否只包含十进制字符。这种方法只存在于unicode对象。 注意:定义一个十进制字符串,只需要在字符串前添加 'u' 前缀即可。 print(number.isdigit()) # 判断是否为十进制整数 print(alpha.islower()) # 判断字母是否全部为小写 print(name.isnumeric()) # 不常用 检测字符串是否只由数字组成。这种方法是只针对unicode对象。注:定义一个字符串为Unicode,只需要在字符串前添加 'u' 前缀即可 print(alpha.isidentifier()) # 检测一个一段字符串是否可以作为变量,即符合变量命名规则 print(alpha.isprintable()) # 不常用 判断是否为可打印字符,linux中设备也是文件形式,此时为不可打印 spa = ' ' print(spa.isspace()) # 判断是否为纯空格 print(name.istitle()) # 判断是否为标题 即每个单词的第一个字符为大写 upper = 'A b' print(upper.isupper()) # 判断字符串中所有的字母是否都为大写 L_join = ['1', '2', '3'] print('-'.join(L_join)) # 输出为 1-2-3 将序列的元素以指定的字符串进行连接 print(upper.ljust(50, '-')) # 返回一个字符串,共50个字符,左对齐,如果不够用‘-’补足 print(upper.ljust(50, '-')) # 返回一个字符串,共50个字符,右对齐,如果不够用‘-’补足 print(name.lower()) # 把所有的字母全部转为小写 print(name.strip('\n')) # 去掉前后换行符\n, 默认是去掉去空格 print(name.lstrip()) # 去掉前面空格 print(name.rstrip('\n')) # 去掉后面换行符 p = str.maketrans('is', '11') # 预设i 》1,s》1,然后对name进行处理,需要一一对应 print(name.translate(p)) print(name.partition('is')) # 指定字符串进行分割,第一个is进行分割,返回三元组,分别为is前的字符,is,is后的字符 print(name.split('H')) # 按指定字符进行分割,连续指定字符则返回''元素,默认空格处理时已经对''进行排除,指定字符没有排除 print(name.splitlines()) # 不论Windows还是linux,如果是多行字符,则按行为元素返回list print(name.startswith(' ')) # 判断是否以指定字符开头,返回True or False print(name.swapcase()) # 大写转小写,小写转大写 print(name.title()) # 转为标题 print(name.upper()) # 转为大写 print(name.zfill(100)) # 返回指定长度的字符串,原字符串右对齐,前面填充0。
三、字典
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen info = dict(st1='java', st2='C++', st3='python') print(info) info['st1'] = 'python' # st1修改为python info['st4'] = 'java' # 添加key为st4,值为java info.setdefault('st5', 'php') # 如果键不存在于字典中,将会添加键并将值设为默认值。如果又则不修改 # del info['st1'] # 通用删除 print(info.pop('st1')) # 删除给定的key,并返回值,必须给定key print(info.popitem()) # 由于dict是无序的,因此是随机删除 并返回key和值的远足 # info.clear() # 清空字典 info2 = info.copy() # 返回一个字典的浅复制 print(info2) info3 = dict.fromkeys([1, 2, 3], ['water', 'fire']) # 通过一个列表生成默认dict,默认值为hello, print(info3) info3[1][0] = 'soil' # 这里有个坑,如果默认值是list这种,则是引用,一改全改 print(info3) print(info.get('st2')) # 通过get来安全的获取值,如果没有返回None,不会抛异常 # print(info['st1']) # 直接取如果没有key st1 则会抛 KeyError 异常 info.items() # 函数以列表返回可遍历的(键, 值) 元组数组。for 循环取值时不建议使用,效率太低,直接遍历key就行 print(info.keys()) # 返回该字典所有的key info4 = dict(st3='html', st10='c', st11='shell') info.update(info4) # 将两个dict合并,由则更新,没有则添加 print(info) print(info.values()) # 函数以列表返回字典中的所有值。 # 循环dict 这样取值比items效率高 for i in info: print(i, info[i])
# 快速创建dict的方法 msg = 'name glen age 26 work it' msg_list = msg.split() print(msg_list) msg_dict = dict(zip(msg_list[0::2], msg_list[1::2])) print(msg_dict) # {'name': 'glen', 'age': '26', 'work': 'it'} >>>a = [1,2,3] >>> b = [4,5,6] >>> c = [4,5,6,7,8] >>> zipped = zip(a,b) # 打包为元组的列表 [(1, 4), (2, 5), (3, 6)] >>> zip(a,c) # 元素个数与最短的列表一致 [(1, 4), (2, 5), (3, 6)] >>> zip(*zipped) # 与 zip 相反,*zipped 可理解为解压,返回二维矩阵式 [(1, 2, 3), (4, 5, 6)]
四、练习
- 打印省、市、县三级菜单
- 可返回上一级
- 可随时退出程序
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen menu = { '四川': { '巴中': ['通江县', '南江县'], '成都': ['双流区', '锦江区', '武侯区'] }, '浙江': { '杭州': ['临安区', '西湖区'], '宁波': ['鄞州区', '奉化市'] } } current_menu = menu layers = [menu] exit_flag = False while not exit_flag: for k in current_menu: print(k) choice = input('please enter:') if choice in current_menu and len(layers) < 3: current_menu = current_menu[choice] layers.append(current_menu) elif choice == 'b' and len(layers) > 1: layers.pop(-1) current_menu = layers[-1] elif choice == 'q': exit_flag = True else: print('input error, retype..') else: print('Browse the end...')
五、练习
购物车程序
1、用户入口:商品信息存在文件里面,已购商品和余额记录在文件里面,启动后直接读取。
2、商家入口:可以添加商品,修改商品价格。
文件:
1、user 用户信息,第一行是购买到的商品,第二行为余额
tv phone refrigerator
30000
2、goods 商品文件格式,商品名称 价格 总数
tv 3000 4
phone 5000 5
refrigerator 4000 2
radio 500 10
用户接口:
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen goods = {} info_user = {} with open('goods', 'r') as f: for line in f.readlines(): list_line = line.split() name0 = list_line[0] price1 = list_line[1] amount2 = list_line[2] goods[name0] = [name0, int(price1), int(amount2)] with open('user', 'r') as f: file_all = f.read().splitlines() user_goods = file_all[0].split() user_balance = file_all[1] info_user['user_goods'] = user_goods info_user['balance'] = int(user_balance) print(info_user) print(goods) exit_flag = False while not exit_flag: print('order', 'name', 'amount') for i in goods: print(i, goods[i][1], goods[i][2]) choice = input('please choice product:') if choice in goods and info_user['balance'] >= goods[choice][1]: info_user['balance'] -= goods[choice][1] info_user['user_goods'].append(choice) goods[choice][2] -= 1 if goods[choice][2] < 1: goods.pop(choice) # print('you balance is', info_user['balance']) print('\033[31;1myou balance is', info_user['balance'], '\033[0m') elif choice in goods: print('\033[31;1myour balance is inadequate...\033[0m') print('\033[31;1myou balance is', info_user['balance'], '\033[0m') elif choice == 'q': exit_flag = True else: print('your enter error...') else: print(goods) print(info_user) print('you balance is', info_user['balance']) with open('goods', 'w') as f: for i in goods: line = ' '.join([str(k) for k in goods[i]]) f.write(line+'\n') print('your goods:', info_user['user_goods']) with open('user', 'w') as f: line_goods = ' '.join([str(k) for k in info_user['user_goods']]) f.write(line_goods+'\n') line_balance = str(info_user['balance']) f.write(line_balance+'\n') print('exit.................')
商户接口
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen # 定义将product_all字典里面的所有商品写入文件的函数 def add_pro(product2): with open('goods', 'w') as f: for k in product2: line2 = ' '.join(product2[k].values()) f.write(line2 + '\n') product = {} # 没批次添加的商品,一级 product_all = {} # 所有商品,二级字典 exit_flag = False # 是否退出输入标志 product_attr = ('pro_name', 'pro_price', 'pro_amount') # 可以添加的商品属性 # 从文件读取所有的商品 with open('goods', 'r') as f: for line in f.readlines(): list_line = line.split() for k, v in enumerate(product_attr): product[v] = list_line[k] product_all[list_line[0]] = product.copy() product.clear() while not exit_flag: for arg in product_attr: user_input = input('\033[31;1madd product {arg}:\033[0m'.format(arg=arg)) if user_input == 'q': exit_flag = True break elif user_input == 'p': for x in product_all: print(x, product_all[x]['pro_price'], product_all[x]['pro_amount']) break elif user_input != 'pro_name' and user_input in product_attr: if not user_input.isdigit(): print('{arg} is number...'.format(arg=arg)) exit_flag = True break else: product[arg] = user_input if len(product) == 3: product_all[product['pro_name']] = product.copy() print('add {pro_name} successful....'.format(pro_name=product['pro_name'])) product.clear() else: add_pro(product_all) print('your add products:', [i for i in product_all])
六、文件操作
打开文件的模式有:
- r,只读模式(默认)。
- w,只写模式。【不可读;不存在则创建;存在则删除内容;】
- a,追加模式。【可读; 不存在则创建;存在则只追加内容;】
"+" 表示可以同时读写某个文件
- r+,可读写文件。【可读;可写;可追加】
- w+,写读
- a+,同a
"U"表示在读取时,可以将 \r \n \r\n自动转换成 \n (与 r 或 r+ 模式同使用)
- rU
- r+U
"b"表示处理二进制文件(如:FTP发送上传ISO镜像文件,linux可忽略,windows处理二进制文件时需标注)
- rb
- wb
- ab
其他操作
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen f = open('aaa', 'r+', encoding='utf-8') # f.write() # 写入文件 # f.readline() # 读取一行,指针位置下以一行到第二行 # f.readlines() # 读取全部文本,根据行来生成一个列表 # result = f.read() # 读取全部类容,返回str # f.close() # 关闭文件 print(f.name) # 读取文件名字本身 print(f.encoding) # 查看编码格式 print(f.errors) # 异常相关 f.fileno() # 返回文件描述符 较少使用 f.isatty() # 如果连接到一个终端设备返回 True,否则返回 False。 如屏幕的标准输出,也可以算写入 f.flush() # 刷新,将在缓存里面的输入立即刷新到磁盘 f.tell() # 返回当前指针的位置,一般以字符数计算 f.seek(0) # 设置指针位置,0标识从头开始读起,对写入文件不起作用,如果在已有数据中直接插入会覆盖磁盘当前位置的数据,因此不能插入 f.readable() # 判断文件是否是以可读模式打开的,是否可读 f.seekable() # 如果文件支持随机存取 f.truncate(20) # 从指针位置截取20个字符,如果没有指定大写截取剩余所有字符 f.writable() # 是否可写模式打开 f.writelines(['hell\n', 'sky']) # 写入一序列的字符串 参数可以位list,需要指定换行,
七、练习
程序练习
程序1: 实现简单的shell sed替换功能
程序2:修改haproxy配置文件
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Glen ha_format = ('global', 'defaults', 'listen', 'frontend', 'backend') index_ha = {} list_tmp = [] ha_dict = {} # 将文件按行读取到list with open('haproxy', 'r', encoding='utf-8') as f1: ha_all = f1.readlines() # 获取每段配置项开始位置 for key in ha_format: key_1 = {} for n, sig in enumerate(ha_all): if key in sig and not sig.startswith(' '): key_1['start'] = n list_tmp.append(n) index_ha[key] = key_1 # 获取每段配置项结束位置 for key in ha_format: start_index = index_ha[key]['start'] index_tmp = list_tmp.index(start_index) if index_tmp+1 < len(list_tmp): index_ha[key]['end'] = list_tmp[index_tmp+1] else: index_ha[key]['end'] = len(ha_all) print(index_ha) # 将文件list转换位dict for key in ha_format: ha_dict[key] = {} ha_dict[key]['record'] = {} for n, line in enumerate(ha_all[index_ha[key]['start']:index_ha[key]['end']]): line_list = line.split() if n == 0: if len(line_list) < 2: ha_dict[key][key] = '' else: ha_dict[key][key] = ' '.join(line_list[1:]) else: if len(line_list) == 0: break elif len(line_list) < 2: ha_dict[key]['record'][line.split()[0]] = '' else: ha_dict[key]['record'][line.split()[0]] = ' '.join(line.split()[1:]) print(ha_dict) # 将配置文件dict写入文件 def write_to_file(ha_dict, ha_format): with open('haproxy2', 'w', encoding='utf-8') as f2: for key in ha_format: line1 = '{key} {par}'.format(key=key, par=ha_dict[key][key]) print(line1) f2.write(line1+'\n') for index in ha_dict[key]['record']: line2 = '\t\t' + index + ' ' + ha_dict[key]['record'][index] f2.write(line2 + '\n') print('\t\t{index} {line2}'.format(index=index, line2=line2)) end_flag = False while not end_flag: item = input('>>') if item in ha_dict: print('{item} {value}'.format(item=item, value=ha_dict[item][item])) for index in ha_dict[item]['record']: print('\t\t' + index + ' ' + ha_dict[item]['record'][index]) elif item == 'q': end_flag = True elif item == 'a': print('add item...') else: print('enter wrong...')