数据类型的操作¶
可下标类型特有的操作¶
索引¶
索引,即下标,从0计起。
# 获取索引对应的元素
x[1]
# 获取元素对应的索引,如果有重复元素则返回第一个的索引
x.index(item)
切片¶
比循环更简洁
# 从头到尾,相当于浅拷贝
_sub[:]
_sub[x:] # x~尾
_sub[:y] # 头~y
# 从x到y,不包含y(前闭后开)
_sub[x:y]
_sub[x:y:n] # 每隔n步取一次,比如取奇数:_sub[1::2]
# 比如去除字符串的最后一位
new_str = old_str[:-1]
反转¶
# 列表自带方法(原对象改变)
_list.reverse()
# 内置函数reversed()反转,反转后得到一个迭代器(原对象不变)
reversed(x)
# 切片方式反转(原对象不变)
x[::-1]
可迭代类型的操作¶
统计¶
# 序列自带方法,统计某元素出现的次数
_str.count("1")
_tuple.count(1)
_list.count(1)
# 统计iterable元素的个数
len(iterable)
# 统计iterable中值最大的
max(iterable)
# 统计iterable中值最小的
min(iterable)
遍历¶
- list
# 迭代时如果移除元素操作,会改变list大小,导致迭代次数与预期不符
# 此时可以迭代list(_list),相当于copy了一个list用于迭代,而实际操作的是原list
for i in _list:
print(i)
- dict
# 遍历键值对
for k, v in _dict.items():
print('key: {}, value: {}'.format(k, v))
# 遍历键
# for k in _dict.keys():
for k in _dict # 可以不加.keys(),而且这样更高效
print(k)
# 遍历值
for v in _dict.values():
print(v)
在迭代字典时不能改变size大小,因为字典的索引是键的哈希表,改变之后将会变成新的对象,迭代器将抛出异常:dictionary changed size during iteration
# 把字典转换为二元列表,然后循环列表来改变字典则不会报错了
for k,v in list(_dict.items()):
pass
数据类型的转换¶
根据不同类型间做运算时会不会自动改变类型,可以分为:
-
弱类型:会,比如:JS
-
强类型:不会(报错),比如:Java、Python
强类型语言可以使用函数做类型转换
- 数值型之间互转
int(1.2) # 1
int(False) # 0
float(1) # 1.0
float(True) # 1.0
bool(0) # False
bool(1.2) # True
- 进制转换
int(x) # 转成十进制
bin(x) # 转成二进制
oct(x) # 转成八进制
hex(x) # 转成十六进制
数值型
与Str
互转
int("123") # 123
float("123") # 123.0
bool("123") # True
str(123) # "123"
str(1.2) # "1.2"
str(True) # "True"
Str
与ASCII码
互转
# max()和min()就是据此返回可迭代对象中元素谁大谁小的
chr(77) # M
ord("a") # 97
Str
与Bytes
互转
_str = "中文"
_bytes = b'\xe4\xb8\xad\xe6\x96\x87'
# 编码,str => bytes
_str.encode('utf-8') # b'\xe4\xb8\xad\xe6\x96\x87'
# 或者
bytes(_str) # 默认encoding='utf-8',可以指定其它
# 解码,bytes => str
_bytes.decode() # 默认解码格式:'utf-8',可以指定其它
- iterable 互转
# iterable如果是字典,默认只取key,取value要用_dict.values()
_tuple = tuple(iterable) # ("a", "b", "c")
_list = list(iterable) # ["a", "b", "c"]
_set = set(iterable) # {"a", "b", "c"} 会自动去重
_set = frozenset(iterable) # frozenset({"a", "b", "c"}) 不可重复且不可变
# iterable to dict
_dict = dict.fromkeys(iterable) # {'a': None, 'b': None, 'c': None}
_dict = dict.fromkeys(iterable, 10) # {'a': 10, 'b': 10, 'c': 10}
# dict to list
_dict = {"a":1, "b":2}
list(.items()) # [('a', 1), ('b', 2)]
# dict to params_str
payload = {"a":1, "b":2}
param_list = [f"{k}={v}" for k,v in list(payload.items())] # ['a=1', 'b=2')]
request_parameters = "?" + "&".join(param_list) # '?a=1&b=2'
数据类型的拼接¶
# 拼接两个字符串
'a' + 'b' # 'ab'
"+".join("abc") # "a+b+c"
"".join(_list) # 将一个列表中的每个元素拼接为一个字符串
# 拼接两个元组
(1,2) + (3,4) # (1,2,3,4)
# 拼接两个列表
[1,2] + [3,4] # [1,2,3,4],生成一个新列表
[1,2].extend([3,4]) # 在原列表中增加
# 拼接两个集合
# 参数可以是任意 iterable,如果是字典只会把key拼接到集合中
_set.update(_iter)
# 拼接两个字典(参数只能是字典)
_dic.update(_dict2)
_dict = {"k1": "v1", **dict2, **dict3, "k4": "v4"}
数据类型的复制¶
- 对于字符串都是引用
- 对于元组,只有深拷贝才不是引用,否则都是引用
以下x为可变数据类型
引用¶
# id(y) == id(x)
# x赋值给y,y只是x的一个引用,会跟着x的改变而改变
y = x
浅拷贝¶
- 工厂函数
.copy()
# id(y) != id(x)
# 只能拷贝父级元素,即改变x的父级元素,y的父级元素不会变
# 子级元素仍为引用,即改变x的子级元素,y的子级元素也会变
y = x.copy()
copy.copy()
函数
import copy
y = copy.copy(x)
- 列表的切片操作也是浅拷贝:
_list[:]
深拷贝¶
# id(y) != id(x)
# 父级与子级元素都会被拷贝,即改变x任意元素,都不会影响y的元素改变
import copy
y = copy.deepcopy(x)
数据类型内置方法¶
哪些方法是有返回值的,哪些是返回None?(可变数据结构的方法都返回None?)
哪些方法不改变原对象,哪些改变,规则是什么?
字符串¶
>>> dir(str)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index',
'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper',
'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
# 查找子串
_str.find(sub_str) # 返回字符串的索引下标,如果不在返回 -1
- 校验
# 判断字符串是否以xxx开头/结尾,可以加索引范围,默认从 0~-1
_str.startswith(xxx, beg=0, end=len(string))
_str.endswith(xxx, beg=0, end=len(string))
_str.isdigit() # 是否全由数字组成
_str.isalpha() # 是否全是字母组成
_str.isupper() # 是否全大写
_str.islower() # 是否全小写
_str.istitle() # 是否标题样式
- 处理
_str.upper() # 变为全大写
_str.lower() # 变为全小写
_str.capitalize() # 将首字母大写
_str.title() # 标题样式,即所有单词首字母大写
_str.swapcase() # 反转大小写,即将大小变小写,小写变大写
_str.strip() # 去除两端的空白,也可以去除指定字符集,下同
_str.lstrip() # 去除左边的空白
_str.rstrip() # 去除右边的空白
"""
注意,去除指定字符的时候,有个容易踩坑的地方
比如下面的结果是 W,而不是 WAI
会把 "IA" 拆分成 I 和 A 分别去除,而不是当做一个整体去匹配
"""
"IAWAI".strip("IA")
# 在指定字符处将字符串分割,组成列表返回
# 指定字符不存在则返回整个字符串
# 指定为空时默认在<空格>\r\n\f\t\v等地方分割
_str.split("x", [分割次数])
"""
"a/b/c/d".split("/", 2) # ["a", "b", "c/d"]
"""
# 把字符串中的“a”替换为“b”
# 注意:不改变原字符串
# 如果要忽略大小写则需要使用正则表达式
_str.replace("a", "b", [替换个数])
"""
tel="12345678888"
tel.replace(tel[3:7], "*"*5) # '123*****8888'
"""
# 可以拼接序列的每一个元素
# 序列为list或tuple时元素必须为字符串类型
_str.join(序列)
"""
"+".join("123") # "1+2+3"
"".join(["a","b","c"]) # "abc" # 字符串转用list(_str)转换为列表后可以再用join转换回字符串
"""
- 格式化
x = "c"
# 方式1:%s、%d
_str = "ab%sde" %x
# 方式2:{}.format()
_str = "ab{}de".format("a")
_str = "ab{0}de{1}".format("a", "b") # 索引指定
_str = "ab{k1}de{k2}".format("k1"="a", "k2"="b") # 关键字指定,也可以**{"k1":1, "k2":2}
# 方式3:f'{}'
f'ab{x}de'
tuple¶
>>> dir(tuple)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'index', 'count']
list¶
>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__',
'index', 'count', 'sort', 'reverse',
'append', 'extend', 'insert',
'pop', 'remove',
'clear', 'copy']
# 列表自带排序方法(原对象会被改变)
_list.sort()
_list.sort(reverse=True) # 倒序
_list.sort(key=len) # 按字符长度排
# 内置函数sorted()排序,元素类型要一致可排,否则报错(原对象不变)
sorted(_list) # 正序
sorted(_list, reverse=True) # 倒序
- 去除列表空字符等
_list = ["aaa", "", "bbb", "\n", " cc\n"]
# 去除列表中空字符串、"\n",以及元素两边的空格等,完美实现
[i.strip() for i in _list if i.strip() != ""] # ['aaa', 'bbb', 'cc']
# 未去除空字符串
[i.strip() for i in _list_] # ['aaa', '', 'bbb', '', 'cc']
# 未去除字符两边的空格等
[i for i in _list_ if i.strip() != ""] # ['aaa', 'bbb', ' cc\n']
# 只能去除空字符串
list(filter(None, _list)) # ['aaa', 'bbb', '\n', ' cc\n']
[x for x in _list if x] # 同上
set¶
dir(set)
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__',
'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'symmetric_difference_update', 'union',
'update',
'add',
'pop', 'remove', 'discard'
'clear', 'copy']
_set.remove("xxx") # 移除,元素不存在会报错
_set.discard("xxx") # 丢弃,元素不存在不会报错
dict¶
>>> dir(dict)
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__',
'fromkeys',
'update',
'get', 'setdefault', 'items', 'keys', 'values',
'pop', 'popitem',
'clear', 'copy']
_dict[key] # 若key不存在,则报错
_dict.get(key, "unkown") # 若key不存在,则默认返回None(可自定义)
_dict.setdefault(key, value) # 若key不存在,则默认将{key:default/value}添加到字典中
# 以下都不接受参数
_dict.items() # dict_items([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])
_dict.keys() # dict_keys(['k1', 'k2', 'k3'])
_dict.values() # dict_values(['v1', 'v2', 'v3'])
Python3.7 开始 dict 是有序的
sorted(_dict.items(), key=lambda x:x[0]) # dict按key排:[('a', 3), ('b', 1), ('c', 2)]
sorted(_dict.items(), key=lambda x:x[1]) # dcit按value排:[('b', 1), ('c', 2), ('a', 3)]
可改变数据类型的操作¶
清空¶
_list.clear()
_set.clear()
_dict.clear()
del _list[:]
增¶
- list
_list.append(x) # x被当作一个整体,添加到末尾
_list.extend(x) # x必须为可迭代的,会被当作一组,组中元素按序添加到末尾
_list.insert(index, x) # x被当作一个整体,插入到指定位置
_list[len(_list):] = x # 末尾插入
- set
_set.add(key)
- dict
_dict["new_key"] = new_value
删¶
.pop()
方法在三种数据类型中用法不太一致,需要参数,不需要参数,指定删除,随机删除,删除末位……擦,真特么乱。
不管怎么删除都会返回被删除的元素。而remove不会。
为什么呢?
因为字典带有key,所以可以带参数(且必须带参数,为什么?),按key删除
而list可以下标,可以带参数下标来删除,如果不带就删除末位
set既没有key也不可下标,所以不能带参数,而且还因为无序,不带参数就随机删除
那么.remove()
呢,list和set都是移除指定元素,dict没有
防止要删除的元素不存在报错,加个默认返回值参数.pop(x, None)
- list
_list.pop() # 删除末位,并返回被删除的值
_list.pop(index) # 删除指定位置
_list.remove(x) # 删除指定元素(如有重复,删除第一个)
- set
_set.pop() # 随机删除,并返回被删除的值
_set.remove(x) # 删除指定元素
- dict
_dict.pop(key) # 删除指定key,并返回被删除key对应的值
_dict.popitem() # 随机删除(但其实删除的是末位,字典现在是有序的),并返回被删除的键值对
- del方式删除,释放内存
del _tuple
del _list
del _set
del _dict
del _list[m:n] # 删除list切片
del _dict[key] # 删除dict指定key
改¶
- list
# 修改指定位置元素
_list[-1] = x
_list[m:m] = x # 还可以用切片的方式替换
- dict
# 同增加
_dict["old_key"] = new_value
字符串去除子串¶
- 使用
str.replace()
original_string = "Hello, World! World is nice."
sub_string_to_remove = "World"
# 去掉所有的 'World'
new_string = original_string.replace(sub_string_to_remove, "")
print(new_string) # 输出: Hello, ! ! is nice.
# 如果只想去掉第一次出现的子串
new_string = original_string.replace(sub_string_to_remove, "", 1)
print(new_string) # 输出: Hello, ! World is nice.
- 使用正则表达式
import re
original_string = "Hello, World! World is nice."
sub_string_to_remove = "World"
# 使用正则表达式去掉所有的 'World'
new_string = re.sub(sub_string_to_remove, "", original_string)
print(new_string) # 输出: Hello, ! ! is nice.
# 只删除第一次匹配的 'World'
new_string = re.sub(sub_string_to_remove, "", original_string, count=1)
print(new_string) # 输出: Hello, ! World is nice.
- 使用
find()
或index()
结合切片
original_string = "Hello, World! World is nice."
sub_string_to_remove = "World"
# 找到子串第一次出现的位置
start = original_string.find(sub_string_to_remove)
if start != -1:
# 计算子串长度
end = start + len(sub_string_to_remove)
# 使用切片去掉子串
new_string = original_string[:start] + original_string[end:]
print(new_string) # 输出: Hello, ! World is nice.
else:
print("子串未找到")
# 只会去掉第一次出现的子串,如果你需要去掉所有匹配的子串,需要循环
pass