跳转至

数据类型的操作

可下标类型特有的操作

索引

索引,即下标,从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"
  • StrASCII码互转
# max()和min()就是据此返回可迭代对象中元素谁大谁小的
chr(77)  # M
ord("a") # 97
  • StrBytes互转
_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