在实际项目中,我们可能一开始为了完成功能而忽视了代码的整体质量,因此,使用一些高阶的函数或方法,能够更加使我们的代码更加优雅。废话不多说,现在马上开始。
enumerate()中也包含了下标和值,可以很方便的进行索引和值的遍历。
data = range(10000) start = time.time() data_len = len(data) for i in range(data_len): print(data[i]) print(time.time() - start) start = time.time() for index, item in enumerate(data): print(index, item) print(time.time() - start)
对于一些有规律的列表需要生成时,建议使用列表生成式进行生成,方便快捷,对于一些属性稍微复杂点的可以使用map进行批量操作。例如生成[1,4,9,16]
print([item * item for item in range(1, 5)])
在对一些复杂对象进行排序时候建议使用sorted进行排序,例如字典的key或者字典的value等
sorted(Iterable, key=Callable)
假设有如下列表中嵌套字典,依据age进行排序
data = [ {"name": "Alex", "age": 18}, {"name": "Band", "age": 21}, {"name": "Coco", "age": 17}, ] print(sorted(data, key=lambda n: n["age"]))
[{'name': 'Coco', 'age': 17}, {'name': 'Alex', 'age': 18}, {'name': 'Band', 'age': 21}]
假设有如下字典,需要将字典按照value值进行排序并返回一个字典
data = {"a": 19, "c": 10, "b": 20} print(dict(sorted(data.items(), key=lambda data: data[1])))
{'c': 10, 'a': 19, 'b': 20}
set集合是无序的,值唯一,可以进行交、并、差等运算操作,除此之外,一般去重也可以使用set进行去重。
data = set({1, 2, 3, 1}) print(data)
一般我们称一个函数或者方法中使用了yield方法进行返回的,则成此方法或者函数为生成器,除了这种方法之外,可以使用类似于列表生成式的方式进行操作,只需要将列表生成式的[]
换成()
即可,示例如下:
l_data = [i for i in range(100)] print(l_data) print(sys.getsizeof(l_data)) g_data = (i for i in range(100)) print(g_data) print(sys.getsizeof(g_data))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] 920 <generator object <genexpr> at 0x0000028E1A626570> 104
使用sys
模块的getsizeof可以获取变量的内存占用。
generator就是生成器,它不会一次性加载全部数据到内存中,只会再for循环调用或者next()\send()方法时进行懒加载方式的输出,极大的减少了内存消耗,尤其是对于数据量较大的情况。
在对于字典的value值的获取中,目前有两种方式,一种是使用索引进行获取,另一种则使用get方法去获取,如下:
data = {"a": 19, "c": 10, "b": 20} print(data["a"]) print(data.get("a", None)) print(data.get("v", None)) print(data["v"])
19 19 None Traceback (most recent call last): File "c:\Users\ts\Desktop\2022.7\2022.7.20\test.py", line 76, in <module> print(data["v"]) KeyError: 'v'
由上述可以看出,在使用索引进行对字典value值的获取时,key存在还好,不存在则会直接报错,而采用get并设置默认值的,则会返回默认值,不会抛出异常。
from collections import Counter s_data = "asdfqwrewasfasdvfare" print(s_data.count("a")) print(Counter(s_data)) l_data = [1, 3, 2, "a", "b", 1, "c", "a", "c"] print(l_data.count("a")) print(Counter(l_data))
4 Counter({'a': 4, 's': 3, 'f': 3, 'd': 2, 'w': 2, 'r': 2, 'e': 2, 'q': 1, 'v': 1}) 2 Counter({1: 2, 'a': 2, 'c': 2, 3: 1, 2: 1, 'b': 1})
由上述可以看见,大部分序列都有一个count方法来获取单个元素的个数,但Counter会统计所有的个数,类似于对于每个元素进行了遍历。
print("key:{}".format("aaa")) key = "aaa" print(f"key:{key}") print("key:%s" % (key))
key:aaa key:aaa key:aaa
不过在实际使用中会发现,在部分常见下f
会引起异常,可使用%s
替代。
适用于多个元素存放在某一个序列中,纯字符串建议使用如下方法。
a = "hello" b = "world" c = "!" print(a + b + c) print("{} {} {}".format(a, b, c)) print(f"{a} {b} {c}") print("%s %s %s" % (a, b, c)) l_data = ["hello", "world", "!"] print(" ".join(l_data))
字典之间的合并可以使用自带的update方法进行合并,注意操作的是原字典;除此之外,也可以使用双星号进行字典的合并。
d1 = {"a": 1, "b": 2} d2 = {"c": 1, "d": 2} d1.update(d2) print(d1) print({**d1, **d2})
切片一般使用[start:end:step]
data = "asdsdfaf" # 选择所有元素 print(data[::]) # 选择从开始到索引为4的元素(不包含4),步长为2的元素 print(data[:4:2]) # 选择从索引为2的位置到索引为7的位置,步长为2的所有元素 print(data[2:7:1]) # 选择最后一个元素到从后向前第6个元素,步长为1的所有元素 print(data[-6:-1:1])
asdsdfaf ad dsdfa dsdfa
与列表生成式类似,但是不常使用
print({item: item + 1 for item in range(10)})
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10}
get
和setdefault
都是获取字典的元素,唯一不同在于get
获取不到元素后不会做任何操作,setdefault
则会将不存在的元素添加至字典中。
data = {"a": 1, "b": 2} print(data.get("c", 12)) print(data) print(data.setdefault("c", 12)) print(data)
如何让python代码写的更加优雅