Python基础03-基本数据类型
基本数据类型
Python基本的数据类型包含6种,分别是:
- 数字:包含整形int、浮点型float、布尔型True/False、复数型complex,不可变类型
- 字符串:str,序列型,用于存储一行字符串或一段文本,不可变类型
- 列表:list,序列型,用于存储多个变量,可变类型
- 元祖:tuple,序列型,用于多个变量表达一个固定组合,不可变类型
- 集合:set,映射型,用于存储多个无序不重复变量,可变类型
- 字典:dict,映射型、用于存储键值对,可变类型
注:另外还有一种NoneType类型,即None,无值
数字
数字类型包含包含整形int、浮点型float、布尔型True/False、复数型complex,是一种不可变类型。
种类
- 整型int:如1、12、9999999,Python3中int长度几乎没有限制。
- 浮点型float:如1.0、99.99
- 布尔型bool
- False:即假,常用与逻辑判断,除False外,Python中的零
0
、字符串零'0'
、浮点数0.0
、空字符串''
、空列表[]
、空元组()
、空集合{}
在逻辑判断时都被认为是False。 - True:即真,除False和上述逻辑判断时被认为False的值以外,都被视为True。
- False:即假,常用与逻辑判断,除False外,Python中的零
- 复数型complex
注:
['']
,[[],[]]
由于不是空列表,在逻辑判断时被认为是True。
操作符
+
:加-
:减*
:乘/
:除,结果为浮点数,如1/2=0.5
,又称真实除//
:整除,舍去所有小数,又称地板除%
:取模,如3 % 2 = 1
**
:乘方,如3 ** 2 = 9
类型转换
- str(): 其他类型转为字符串, 如
str(12)
- int():字符串整数或浮点数转为整型,如
int("12")
- float():字符串数字或整形,转换为浮点数,如
float("1.23")
注:字符串形式的浮点数,如'1.23',只能使用float转为浮点数,用int转为整数则会报错。
进制转换
Python中的数字除了10进制数之外,还支持2进制(表示为0b开头)、8进制(表示为0o开头)、16进制数(表示为0x开头)。相互转换方法如下:
- bin():转为2进制,如
bin(10)
,结果为0b1010
- oct():转为8进制,如
oct(10)
,结果为0o12
- hex():转为16进制,如
hex(10)
,结果为0xa
- int():转为10进制,如
int(0b1010)
结果为10
字符串
字符串系统方法
方法 | 说明 | 示例 |
---|---|---|
len() | 计算字符串长度 | len("abcdefg"),结果为7 |
count() | 查询字符串中某个元素的数量 | aabcabc".count("a"),结果为3 |
find() / index() | 查找字符串中某个字符第一次出现的索引,find()找不到返回-1 , index()找不到报错 | "abcdefg".find("b"),结果为1 , ”abcdefg".index("b"),结果也为1 |
replace() | 替换字符串中的某部分 | "hello,java".replace("java", "python"),结果为hello,python |
split() | 将字符串按分隔符分割成列表 | "a,b,c,d".split(","),结果为["a", "b", "c", "d"] |
join() | 将字符串作为分隔符连接列表元素得到一个字符串 | "-".join(["a", "b", "c", "d"]),结果为a-b-c-d |
lower() / upper() | 将字符串转换为全小写/大写 | "AbcdeF".lower(),结果为abcdef , "abcedF".upper(),结果也为ABCDEF |
isdigit() / isalpha() / isalnum() | 字符串是否纯数字/纯字母/纯数字字母组合 | "123".isdigit(),结果为True |
strip() / lstrip() / rstrip() | 去掉字符串左右/左边/右边的无意字符(包括空格、换行等非显示字符) | " this has blanks \n".strip(),结果为this has balnks |
字符串格式化
字符串格式化是指,将字符串的某部分按一定格式输出,同时也可以将某些变量的实际值,插入到字符串中。
- %: 如
"Name: %s, Age: %d" % ("Lily", 12)
或"Name: %(name)s, Age: %(age)d" % {"name": "Lily", "age": 12}
- format: 如
"Name: {}, Age: {}".format("Lily", 12)
或"Name: {name}, Age: {age}".format(name="Lily",age=12)
- fstring:如
f'Name: {name}, Age: {age}'
- substitude(不完全替换会报错)/safe_substitude: 如
"Name: ${name}, Age: ${age}".safe_substitude(name="Lily",age=12)
示例: 利用format生成自定义html报告
tpl='''<html>
<head><title>{title}</title></head>
<body>
<h1>{title}</h1>
<table border=1px>
<tr>
<th>序号</th>
<th>用例</th>
<th>结果</th>
</tr>
{trs}
</table>
</body>
</html>
'''
tr='''<tr><td>{sn}</td>
<td>{case_name}</td>
<td>{result}</td>
'''
title="自动化测试报告"
case_results = [("1", "test_add_normal", "PASS"),("2", "test_add_negative", "PASS"), ("3", "test_add_float", "FAIL")]
trs=''
for case_result in case_results:
tr_format = tr.format(sn=case_result[0], case_name=case_result[1], result=case_result[2])
trs += tr_format
html = tpl.format(title=title, trs=trs)
f = open("report.html", "w")
f.write(html)
f.close()
结果预览:
自动化测试报告
序号 | 用例 | 结果 |
---|---|---|
1 | test_add_normal | PASS |
2 | test_add_negative | PASS |
3 | test_add_float | FAIL |
列表 list
列表元素支持各种对象的混合,支持嵌套各种对象,如
["a", 1, {"b": 3}, [1,2,3]]
- 列表操作
- 赋值:
l = [1, "hello", ("a", "b")]
- 获取:
a = l[0] # 通过索引获取
- 增:
l.append("c");l.extend(["d","e"]);l+["f"]
- 删:
l.pop() # 按索引删除,无参数默认删除最后一个;l.remove("c") # 按元素删除
- 改:
l[1]="HELLO" # 通过索引修改
- 查: 遍历
for i in l: print(i)
- 列表系统方法
方法 | 说明 | 示例 |
---|---|---|
append()/insert()/extend() | 添加/插入/扩展(连接) | [1,2].append(3) |
insert() | 插入 | [1,3].insert(1,2) |
extend() | 扩展(连接) | [1,2].extend([3,4]) |
index() | 获取元素索引 | [1,2].index(2) |
count() | 统计元素个数 | [1,2,1,1].count(1) |
pop() | 按索引删除 | [1,2].pop(0) |
remove() | 按元素删除 | [1,2].remove(1) |
sort() | 排序 | [1,3,2].sort() |
reverse() | 反转 | [1,3,2].reverse() |
案例: 字符串反转
s="abcdefg"
r=''.join(reversed(a))
元组 tuple
- 不可改变,常用作函数参数(安全性好)
- 同样支持混合元素以及嵌套
- 只有一个元素时,必须加","号,如
a=("hello",)
- 因为Python中()还有分组的含义,不加","会识别为字符串
为什么需要元祖?有时候我们需要多个变量来表达一个确定的值,如坐标(x,y)。在哈希算法中,不可变是非常重要的,这样每次生成的哈希值才能相同。作为不可变对象,元祖可以作为字典的KEY,即
{(1,2): 3}
是合法的。
字符串/列表/元组统称为序列, 有相似的结构和操作方法
元祖对象操作方法
由于元素是不可变对象,自带操作对象较少。
方法 | 说明 | 示例 |
---|---|---|
index() | 获取元素索引 | t=(1,2,3); print(t.index(2) |
count() | 获取元素个数 | t=(1,2,3,2,1,2,3); print(t.index(2) |
序列相关操作方法
字符串、列表、元祖等按顺序存储的变量类型,我们统称为序列类型。
索引
- 正反索引:
l[3];l[-1]
- 索引溢出(IndexError): 当索引大于序列的最大索引时会报错,如[1,2,3,4]最大索引是3,引用l[4]会报IndexError
切片
- l[1:3] # 从列表索引1到索引3(不包含索引3)进行截取, 如 l = [1, 2, 3, 4, 5], l[1:3]为[2, 3]
- l[:5:2] # 第一个表示开始索引(留空0), 第二个表示结束索引(留空为最后一个,即-1), 第三个是步长, 即从开头到第5个(不包含第5个),跳一个取一个
- 案例: 字符串反转
s="abcdefg";r=s[::-1]
遍历
- 按元素遍历:
for item in l: print(item)
- 按索引遍历:
for index in range(len(l)): print(l[index])
- 按枚举遍历:
for i,v in enumerate(l): print((i,v))
扩展/连接(添加多个元素)
extend()/+ "abc"+"123";[1,2,3]+[4,5];[1,2,3].extend([4,5,6,7])
类型互转: str()/list()/tuple()
list转str一般用join(), str转list一般用split()
系统函数
- len(): 计算长度
- max()/min(): 求最大/最小元素
- sorted()/reversed(): 排序/反转并生成新序列(sort()/reverse()直接操作原序列)
l_new=sorted(l);l_new2=reversed(l)
集合 set
集合是Python中一种映射类型,集合中的元素要是不可变类型(数字、字符串、元祖),元素不重复(自动去重)。
由于集合是基于映射类型(基于hash算法计算得到的元素地址,而不是顺序排列),相比于列表和元祖,集合的查询效率非常高,无论集合中有多少个元素,查询某个元素只需要一次操作。
集合中元素是没有顺序的。另外在Python中有可变结合set和不可变集合frozenset两种。
创建集合
s = {'a', 'b', 'c'}
s = set() # 创建空集合
s = set(['a', 'b', 'c']) # 将列表转为集合
集合操作
同数学概念中的集合,Python中的集合也支持交集、并集、差集等操作,集合于集合常见操作符如下:
- 联合(并集): 例如:
{'a', 'b' } | {'b', 'c'}
,结果为{'a', 'b', 'c'}
- 交集:
&
: 例如:{'a', 'b' } | {'b', 'c'}
,结果为{'b'}
- 差集: 例如:
{'a', 'b' } - {'b', 'c'}
,结果为{'a'}
,相反{'b', 'c' } - {'a', 'b'}
,结果为{'c'}
- 对称差分(去除相同的项做并集): 例如
{'a', 'b' } ^ {'b', 'c'}
结果为{'a', 'c'}
利用集合操作可以快速对比出一些数据的不同,例如
data1 = [{'name': '王六', 'score': 75},
{'name': '张三', 'score': 98},
{'name': '赵六', 'score': 89},
{'name': '李四', 'score': 87},
{'name': '李五', 'score': 87}]
data2 = [{'name': '赵六', 'score': 89},
{'name': '李四', 'score': 98},
{'name': '张三', 'score': 98},
{'name': '王五', 'score': 75},
{'name': '王六', 'score': 85}]
# 将列表中的每一项转为value值组成的不可变元祖, 然后将列表转为集合
set1 = set([tuple(i.values()) for i in data1])
set2 = set([tuple(i.values()) for i in data2])
print('data2中于data1中不同的有', set1-set2)
print('data1中于data2中不同的有', set2-set1)
做两次差集是除了差异值,还输出data1中有data2中没有及data2中有data1中没有的值, 运行后结果如下:
data2中于data1中不同的有 {('李四', 87), ('王六', 75), ('李五', 87)}
data1中于data2中不同的有 {('王六', 85), ('王五', 75), ('李四', 98)}
集合对象自带方法
add()/update()/remove()/discard()/pop()/clear()
方法 | 说明 | 示例 |
---|---|---|
add() | 添加元素 | s = set(); s.add('a') |
update() | 更新集合(批量添加多个) | s = {'a', 'b'}; s1=set(['b', 'c']); s.update(s1) |
remove(element) | 移除指定元素(如果元素不存在报错) | s = {'a', 'b', 'c'}; s.remove('a') ;print(s) |
discard(element) | 丢弃指定元素(如果元素不存在不报错) | s = {'a', 'b', 'c'}; s.discard('d') ;print(s) |
pop() | 随机移除一个元素 | s={'a', 'b', 'c'}; s.pop(); print(s) |
copy() | 复制集合 | s = {'a', 'b', 'c'}; s1 = s.copy(); print(s1) |
clear() | 清空集合 | s = {'a', 'b', 'c'}; s.clear() ; print(s) |
difference(s1) | 与另一个集合的差别(相当于差集) | s = {'a', 'b'};s1 = {'b', 'c'};print(s.difference(s1)) |
issubset(s1) | 是否子集 | s = {'a', 'b'}; s1 = {'a', 'b', 'c'}; print(s.issubset(s1)) |
issuperset(s) | 是否父集 | s = {'a', 'b'};s1 = {'a', 'b', 'c'}; print(s1.issuperset(s)) |
isdisjoint(s) | 是否互斥(彼此都不包含对方元素) | s = {'a', 'b'};s1 = {'c', 'd'}; print(s1.isdisjoint(s)) |
案例1: 列表去重:
l=[1,2,3,1,4,3,2,5,6,2];l=list(set(l))
(由于集合无序,无法保持原有顺序)
案例2: 100w条数据,用列表和集合哪个性能更好? - 集合性能要远远优于列表, 集合是基于哈希的, 无论有多少元素,查找元素永远只需要一步操作, 而列表长度多次就可能需要操作多少次(比如元素在列表最后一个位置)
字典 dict
- 字典是由若干key-value对组成, Python3.6后字典是有序的, 字典的key不能重复,而且必须是可哈希的,通常是字符串
- 字典操作
- 赋值:
d = {"a":1, "b":2}
- 获取:
a = d['a']
或a = d.get("a") # d中不存在"a"元素时不会报错
- 增:
d["c"] = 3; d.update({"d":5, "e": 6}
- 删:
d.pop("d"); d.clear() # 清空
- 查:
d.get("c")
- 遍历:
- 遍历key:
for key in d:
或for key in d.keys():
- 遍历value:
for value in d.values():
- 遍历key-value对:
for item in d.items():
- 遍历key:
字典常用操作
方法 | 说明 | 示例 |
---|---|---|
get(key, default=None) | 获取指定键的值,如果不存在该键,则返回default默认值, | d = {'a': 1, 'b': 2, 'c': 3}; print(d.get(e, 5)) |
setdefault(key, default) | 设置没有字典中该项时的默认值 | d = {'a': 1, 'b': 2, 'c': 3}; d.set_default('e', 5); print(d['e']) |
keys() | 所有键的集合(类似列表) | d = {'a': 1, 'b': 2, 'c': 3}; print(d.keys()) |
values() | 所有值的集合(类似列表) | d = {'a': 1, 'b': 2, 'c': 3}; print(d.values()) |
items() | 所有key, value对的集合(类似列表) | d = {'a': 1, 'b': 2, 'c': 3}; print(d.items()) |
copy() | 复制字典(浅拷贝) | d = {'a': 1, 'b': 2, 'c': 3}; d2 = d.copy(); print(d2) |
update(...) | 更新字典 | d = {'a': 1, 'b': 2, 'c': 3}; d.update({'c': 4, 'd': 5}; print(d) |
clear() | 清空字典 | d = {'a': 1, 'b': 2, 'c': 3}; d.clear(); print(d) |
pop(key) | 取出(移除)指定key并获取对应的值 | d = {'a': 1, 'b': 2, 'c': 3}; b_value = d.pop('b'); print(d) |
popitem() | 取出(移除)末尾的key-value对 | d = {'a': 1, 'b': 2, 'c': 3}; print(d.popitem()) |
另外还有两个创建字典的方法:
- dict(key1=value1, key2=value2, ...): 创建字典,例如
d = dict(a=1, b=2, c=3)
,等同于d = {'a': 1, 'b': 2, 'c': 3}
- dict.fromkeys(key1, key2, key3, ... , default): 以默认值创建包含多个键的字典,例如
d = dict.fromkeys(['a', 'b', 'c'], 1)
,等同于d={'a': 1, 'b': 1, 'c': 1}
案例: 更新接口参数 api = {"url": "/api/user/login": data: {"username": "张三", "password": "123456"}},将username修改为"李四"
api['data']['username'] = "李四"
或 api['data'].update({"username": "李四"})
哈希与可哈希元素
- 哈希是通过计算得到元素的存储地址(映射), 这就要求不同长度的元素都能计算出地址,相同元素每次计算出的地址都一样, 不同元素计算的地址必须唯一, 基于哈希的查找永远只需要一步操作, 计算一下得到元素相应的地址, 不需要向序列那样遍历, 所以性能较好
- 可哈希元素: 为了保证每次计算出的地址相同, 要求元素长度是固定的, 如数字/字符串/只包含数字,字符串的元组, 这些都是可哈希元素
6种类型简单的特点总结
不可变类型:数字/字符串/元祖/frozen set
可变类型:列表、集合、字典
有序类型:序列(字符串/列表/元祖
无序类型:集合、字典