Python基础二(数据类型介绍)
一、引言
1 、什么是数据?
x=10,10是我们要存储的数据
2 、为何数据要分不同的类型
数据是用来表示状态的,不同的状态就应该用不同的类型的数据去表示
3 、数据类型
数字
字符串
列表
元组
字典
集合
二、基础数据类型
1、数字int:用于计算
int(整型)-- 12,3,45
+ - * / //
% 取余数、** 幂、// 整除
在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1
在64位系统上,整数的位数为64位,取值范围为-2**63~2**63-1
Python3里不再有long类型,全是int型
还有float--浮点型, 复数型:(略)
.bit_length() -- 十进制转二进制后的位数
i = 100 print(i.bit_length()) # 7
2、布尔值bool:用于判断
布尔值 True False
数字转换bool:0--False 非0--True
i = 3 b = bool(i) print(b) # True
bool转换数字:False--0 True--1
b = True i = int(b) print(i) # 1
PS -- while 1: 比 while True: 效率高
3、字符串str:存储、操作少量字符
str -- python当中凡是用引号(单、双、三)引起来的都是字符串。
可相加: 字符串的拼接,双方都只能是字符串。
i = 18 print('今年' + str(i) + '岁')
可相乘:str * int,重复字符串
print('坚强' * 8)
字符串转化成数字:int(str) 条件:str必须是数字组成的
s = '123' i = int(s)
数字转化成字符串:str(int)
i = 1
s = str(i)
字符串转化成bool:空字符串--False 、非空字符串--True
s = input('请输入:') if s: print('输入不为空!') else: print('你输入的为空,请重新输入!')
字符串索引与切片:
索引即下标,就是字符串组成的元素从第一个开始,初始索引为0,以此类推
a = 'ABCDEFGHIJK' print(a[0]) # A print(a[3]) # D print(a[-1]) # K print(a[-2]) # J
切片就是通过索引(索引:索引:步长)截取字符串的一段,形成新的字符串(原则就是顾头不顾尾)
a = 'ABCDEFGHIJK' print(a[0:3]) # ABC print(a[2:5]) # 默认步长1 print(a[0:]) # 默认到最后 print(a[0:-1]) # -1是列表中最后一个元素的索引,但是要满足顾头不顾腚的原则,所以取不到K元素 print(a[0:5:2]) # 加步长 print(a[5:0:-2]) # 反向步长
字符串常用方法:
# capitalize,title,upper,lower,swapcase name = 'william-Shaw' print(name.capitalize()) # 首字母大写 William-shaw print(name.title()) # 每个隔开(字符、数字)单词的首字母大写 William-Shaw print(name.upper()) # 全字母大写 print(name.lower()) # 全字母小写 print(name.swapcase()) # 大小写翻转 # 居中:总长度,空白处填充 print(name.center(20,"*")) # ****william-Shaw**** # 数字符串中的元素出现的个数。 print(name.count("i",0,4)) # 可切片 # 长度--字符个数 print(len(name)) # 前面的补全 # 默认将一个tab键变成8个空格,如果tab前面的字符长度不足8个,则补全8个, # 如果tab键前面的字符长度超过8个不足12个则补全12个,以此类推。 s1 = "shaw " print(s1) s2 = "shaw" print(s2.expandtabs()) # 效果同 s3 = "dkfjdkfasf54" # startswith 判断是否以...开头 # endswith 判断是否以...结尾 print(s3.endswith('jdk',3,6)) # T 顾头不顾腚 返回的是布尔值 print(s3.startswith("kfj",1,4)) # T # 寻找字符串中的元素是否存在 print(s3.find("fjdk",1,6)) # 2 返回的找到的首个元素的索引,如果找不到返回-1 print(s3.index("fjdk",4,6)) # 报错 返回的找到的元素的索引,找不到报错。 # split 以...为分割,最终转换成一个列表,此列表不含有这个分割的元素。 print('title,Title,atre,'.split(',')) # ['title','Title','atre',''] print('title,Title,atre,'.rsplit(',',2)) # ['title,Title','atre',''] # format的三种玩法 格式化输出 s = '{} {} {}'.format('egon',18,'male') # 顺序填充 s = '{1} {0} {1}'.format('egon',18) # 按索引填充 s = '{name} {age} {sex}'.format(sex='male',name='egon',age=18) # 按名称填充 # strip 去空格 name = '&william**' print(name.strip()) # 默认去除两端空格 print(name.strip('*&')) # william print(name.lstrip('*&')) # william** print(name.rstrip('*&')) # &william # replace 替换 name = 'willam say : my name is william' print(name.replace('william','bill')) print(name.replace('william','bill',1)) # is系列 name = 'william123' print(name.isalnum()) # T 字符串由字母或数字组成 print(name.isalpha()) # F 字符串只由字母组成 print(name.isdigit()) # F 字符串只由数字组成
4、列表list:存储、操作大量数据
list -- [ ,,]
列表是python中的基础数据类型之一,里面可以存放各种数据类型
比如:li = ['bill', 123, Ture, (1,2,3,'bill'), [1,2,3,'小明', ], {'name':'bill'}]
列表相比于字符串,不仅可以储存不同的数据类型,而且可以储存大量数据
32位python的限制是 536870912 个元素
64位python的限制是 1152921504606846975 个元素
列表是有序的,有索引值,可切片,方便取值(同字符串):
li = ['bill', 123, Ture, (1,2,3,'bill'), [1,2,3,'小明', ], {'name':'bill'}] l1 = li[0] print(l1) l2 = li[1] print(l2) l3 = li[0:3] print(l3)
增:对原列表进行操作
li = [1,'a','b',2,3,'a'] li.insert(0,55) # 按照索引去增加-添加到索引位置 print(li) li.append('aaa') # 增加到最后 li.append([1,2,3]) print(li) li.extend(['q,a,w']) # 迭代的去增-必须是可迭代对象 li.extend(['q,a,w','aaa']) li.extend('abc') li.extend('a,b,c') print(li)
# 持续添加输入元素(输入Q退出) li = [] while 1: username = input('>>>') if username.strip().upper() == 'Q': break li.append(username) print(li)
删:
l1 = li.pop(1) # 按照索引去删除,有返回值 l2 = li.pop() # 默认删除最后一个非空元素 print(l1,l2) del li[1:3] # 按照索引去删除,可切片删除,没有返回值 print(li) li.remove('a') # 按照元素值去删除,无返回值 print(li) li.clear() # 清空列表-- [] del li # 完全删除列表
改:(无 replace())
li = [1,'a','b',2,3,'a'] li[1] = 'dfasdfas' # 按照索引去修改 print(li) li[1:3] ='fdssf' # 按照切片迭代修改 print(li) li[1:3] = [1,2,'dde'] print(li)
查:按照索引、切片、循环去查
for i in li: print(i)
其他操作:len、count、index(无find)、sort、reverse、join
# len 统计长度 li = ["q","w","q","r","t","y"] l = len(li) print(l) # count(数)(统计某个元素在可迭代对象中出现的次数) print(li.count("q")) # index (用于从可迭代对象中找出某个值第一个匹配项的索引位置) print(li.index("q")) # sort (用于在原位置对可迭代对象进行排序) li = [2,1,3,4,5] li.sort() # 正向排序--没有返回值,只能打印li print(li) li.sort(reverse = True) # 反向排序--没有返回值 print(li) # reverse (将可迭代对象中的元素反向存放) li = [2,1,3,4,5] li.reverse() # 列表反转--没有返回值,只能打印a print(li) # join (将可迭代对象每个元素用字符串连接,形成新字符串) # 列表转化成字符串 list -----> str li = ['bill','shaw','william',123,321] s = '++'.join(li) print(s,type(s))
列表的嵌套:嵌套可迭代对象
li = ['william','武藤','常昊',['bill',87],23] print(li[1][1]) li[0] = li[0].capitalize() li[0][0] = li[0][0].lower() li[2] = li[2].replace('昊','日天') li[2] = '常日天' li[3][0][0] = li[3][0][0].upper() print(li)
5、元祖tuple:存储只读数据
tuple -- ( ,,)
元组被称为只读列表,即数据可以被查询,但不能被增删改
元素(儿子)不能改,但元素里的元素(孙子)可能被修改
tu = (1,2,3,'bill',[2,3,4,'william'],'shaw') # 查询和遍历 print(tu[3]) print(tu[0:4]) for i in tu: print(i) tu[4][3]=tu[4][3].upper() # 列表元素'william'改成大写 print(tu) tu[4].append('SB') # 列表可追加 print(tu)
6、字典dict:存储、操作关系型数据(键值对形式)
dict -- { k : v,k : v,k : v }
字典是python中唯一的映射类型,采用键值对(key-value)形式存储数据
python对key进行哈希函数运算,根据计算的结果决定value的存储地址
字典是无序存储的,key必须是不可变数据类型(可哈希),如:
数字、字符串、布尔值、元祖
字典当中的元素是通过键key来存取的,而不是通过偏移存取。
特点:存储关系型数据,查询速度快(二分法),无序(3.5版本以前)
增:
dic = {'age': 18, 'name': 'bill', 'sex': 'male'} dic['high'] = 175 # 没有键值对,则添加 dic['age'] = 16 # 如果有键,则值覆盖 print(dic) dic.setdefault('weight') # 有键值对,不做任何改变,没有才添加。 dic.setdefault('weight',150) dic.setdefault('name','william') print(dic)
删:
dic = {'age': 18, 'name': 'bill', 'sex': 'male'} print(dic.pop('age')) # 按键去删除键值对,返回对应的值 print(dic.pop('high', '没有此键')) # 可设置默认返回值 无键就返回此值 print(dic) print(dic.popitem()) # V3.6默认删除最后一个键值对 返回键值对元祖 print(dic) del dic['name'] # 按照键删除 没有键会报错 无返回值 print(dic) dic_ = dic.clear() # 清空字典 返回None print(dic, dic_) # {} None del dic # 完全删除字典 无返回值
改:
dic = {"name":"bill", "age":18, "sex":"male"} dic["name"] = "william" print(dic) dic1 = {"name":"bill", "weight":65} dic1.update(dic) # 将dic所有的键值对覆盖添加(相同的覆盖,没有的添加)到dic1中 print(dic) print(dic1)
查:
dic = {'age': 18, 'name': 'bill', 'sex': 'male'} print(dic.keys()) # 返回列表,元素是键 print(dic.values()) # 返回列表,元素是值 print(dic.items()) # 返回列表,元素是键值对元祖 for i in dic.keys(): # 遍历字典键 print(i) for i in dic.values(): # 遍历字典值 print(i) for i in dic: # 默认遍历字典键 print(i) for k,v in dic.items(): # 遍历字典键值对 print(k,v) print(dic['name']) # 没有键 会报错 print(dic.get('name1','没有这个键')) # 没有键 返回设定值 默认是 None
# 并列声明变量 a,b = 1,2 print(a,b) # 1 2 a = 1 b = 2 a,b = b,a print(a,b) # 2 1 a,b = [1,2],[2,3] print(a,b) # [1,2] [2,3] a,b = (1,2) print(a,b) # 1 2 a,b = [1,2] print(a,b) # 1 2
字典嵌套:
dic = { 'name':['bill','william','shaw'], 'py':{ 'time':'1314', 'money':1980, 'addr':'CBD', }, 'age':21 } dic['age'] = 56 dic['name'].append('ritian') dic['name'][1] = dic['name'][1].upper() dic['py']['sex'] = 'male' print(dic)
7、集合set:不常用
set -- { ,,}
无序、不重复的数据集合,里面的元素是不可变类型(可哈希)
集合本身是可改变类型(不可哈希),所以集合做不了字典的键
去重 -- 把一个列表变成集合,就自动去重了
关系测试 -- 测试两组数据之前的交集、差集、并集等关系。
创建:
set1 = set({1,2,3}) set2 = {'bill', 'william', 1, True, (1,2)} print(set1) print(set2)
增:
# add set1.add('女神') print(set1) # update set2.update('abc') print(set2)
删:
print(set1.pop()) # 随机删除,有返回值 print(set1) set1.remove('bill') # 按元素删除,无元素报错 print(set1) set1.clear() # 清空集合 print(set1) del set1 # 删除集合
查:
for i in set1: print(i)
去重:
li = [1,2,33,33,2,1,4,5,6,6] set1 = set(li) li = list(set1) print(li)
其他操作:交、并、差、反交、子、超
交集( & 、 intersection):
set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} set3 = set1 & set2 print(set3) # {4, 5} print(set1.intersection(set2)) # {4, 5}
并集( | 、 union):
set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} print(set1 | set2) # {1, 2, 3, 4, 5, 6, 7,8} print(set2.union(set1)) # {1, 2, 3, 4, 5, 6, 7}
差集( - 、difference):
set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} print(set1 - set2) # {1, 2, 3} print(set2.difference(set1)) # {6, 7, 8}
反交集( ^ 、symmetric_difference):
set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} print(set1 ^ set2) # {1, 2, 3, 6, 7, 8} print(set1.symmetric_difference(set2)) # {1, 2, 3, 6, 7, 8}
子集与超集(< issubset 、> issuperset):
set1 = {1,2,3,} set2 = {1,2,3,4,5,6} print(set1 < set2) print(set1.issubset(set2)) # 这两个相同,都是说明set1是set2子集。 print(set2 > set1) print(set2.issuperset(set1)) # 这两个相同,都是说明set2是set1超集。
不可变集合(frozenset),只能查:
set1 = frozenset('barry') print(set1,type(set1)) for i in set1: print(i)
8、数据类型总结
按存储空间的占用分(从低到高):
数字
字符串
集合:无序,即无序存索引相关信息
元组:有序,需要存索引相关信息,不可变
列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改
按存值个数区分:
原子类型 -- 数字、字符串、布尔值
容器类型 -- 列表、元祖、字典、集合
按可变不可变区分:
可变 -- 列表、字典
不可变 -- 数字、字符串、布尔值、元祖
按访问顺序区分:
直接访问 -- 数字 顺序访问(序列)-- 字符串、列表、元祖 键值访问(映射)-- 字典
9、其他(for,enumerate,range)
for循环:按照顺序循环可迭代对象
# 遍历字符串 msg = 'william-shaw' for s in msg: print(item) # 遍历列表 li = ['bill','比尔','男神','云鹤'] for i in li: print(i) # 遍历字典 dic = {'name':'william','age':18,'sex':'m'} for k,v in dic.items(): print(k,v) # 循环嵌套 li = [1,2,3,5,'bill',[2,3,4,5,'william'],'shaw'] for i in li: if type(i) == list: for k in i: print(k) else: print(i)
range:指定范围,生成指定数字(顾头不顾尾)
for i in range(3,10): # 3 - 9 print(i) for i in range(10): # 默认 从0开始 print(i) for i in range(0,10,3): # 步长3 print(i) for i in range(10,0,-2): # 反向步长 不含 0 print(i) for i in range(10,-1,-2): # 反向步长 包含 0 print(i) for i in range(0,10,-1): # 不报错,返回空 print(i)
enumerate:枚举
将可迭代对象组成一个索引序列,利用它可以同时获得索引和值
li = ['bill','billy','william','will','shaw'] for i in enumerate(li): # 索引和元素的元祖 print(i) for index,name in enumerate(li,1): # 起始位置默认是0,可更改 print(index, name)
三、深浅copy
1, 赋值运算
对于赋值运算来说,l1与l2指向的是同一个内存地址,完全一样。
l1 = [1,2,3,['bill','billy']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['bill','billy']] print(l2) # [111, 2, 3, ['bill','billy']] l1[3][0] = 'william' print(l1) # [111, 2, 3, ['william','billy']] print(l2) # [111, 2, 3, ['william','billy']]
2,浅拷贝--copy
对于浅copy来说,第一层创建的是新的内存地址;
而从第二层开始,指向的都是同一个内存地址。
l1 = [1,2,3,['bill','billy']] l2 = l1.copy() print(l1,id(l1)) # [1, 2, 3, ['bill','billy']] 2380296895816 print(l2,id(l2)) # [1, 2, 3, ['bill','billy']] 2380296895048 l1[1] = 222 print(l1,id(l1)) # [1, 222, 3, ['bill','billy']] 2593038941128 print(l2,id(l2)) # [1, 2, 3, ['bill','billy']] 2593038941896 l1[3][0] = 'william' print(l1,id(l1[3])) # [1, 2, 3, ['william','billy']] 1732315659016 print(l2,id(l2[3])) # [1, 2, 3, ['william','billy']] 1732315659016 # l2 = l1[:] 与 l2 = l1.copy() 一样
3,深拷贝--deepcopy
对于深copy来说,两个是完全独立的,改变任意一个的元素(无论多少层),另一个绝对不改变。
import copy l1 = [1,2,3,['bill','billy']] l2 = copy.deepcopy(l1) print(l1,id(l1)) # [1, 2, 3, ['bill','billy']] 2915377167816 print(l2,id(l2)) # [1, 2, 3, ['bill','billy']] 2915377167048 l1[1] = 222 print(l1,id(l1)) # [1, 222, 3, ['bill','billy']] 2915377167816 print(l2,id(l2)) # [1, 2, 3, ['bill','billy']] 2915377167048 l1[3][0] = 'wusir' print(l1,id(l1[3])) # [1, 222, 3, ['william','billy']] 2915377167240 print(l2,id(l2[3])) # [1, 2, 3, ['bill','billy']] 2915377167304
案例练习:
1、元素分类:
''' 有一列表,li= [11,22,33,44,55,66,77,88,99,90],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。 即: {'k1': 大于66的所有值列表, 'k2': 小于66的所有值列表} '''
li= [11,22,33,44,55,66,77,88,99,90] dic ={} li_greater=[] #大于66的所有值列表 li_less=[] #小于66的所有值列表 for i in li: if i == 66: pass elif i > 66 : li_greater.append(i) else: li_less.append(i) dic.setdefault('k1', li_greater) dic.setdefault('k2', li_less) print(dic)
2、购物车输出:
''' 输出商品列表, li = ["手机", "电脑", '鼠标垫', '游艇'],用户输入序号,添加用户选中的商品 要求:1:页面显示 序号 + 商品名称,如: 1 手机 2 电脑 … 2:用户输入选择的商品序号,打印商品名称,并添加购物车 3:如果用户输入的商品序号有误,则提示输入有误,并重新输入。 4:用户输入Q或者q,退出程序。 '''
li = ["手机", "电脑", "鼠标垫", "游艇"] cart = [] flag = True while flag: for i in li: print('{} {}'.format(li.index(i)+1,i)) choice = input('请输入选择的商品序号/输入Q或者q退出程序:') if choice.isdigit(): choice = int(choice) if 0 < choice <= len(li): cart.append(li[choice-1]) print(li[choice-1],'已加入购物车!') else: print('请输入有效数字!') elif choice.upper() == 'Q': flag = False else: print('请输入数字!') else: print('已退出!') if cart != []: print('购物车列表为:' ) print(cart)