《Python进阶》学习笔记
1. *args 和 **kwargs
*args 是用来发送一定长度的键值对, 作为参数传递给一个函数。
2. 调试 Debugging
命令行使用Python debugger运行一个脚本: $ python -m pdb my_script.py
pdb模块(断点调试)用法:
import pdb
功能:断点设置,单步执行,查看代码,查看函数,追踪变量等
pdb.set_trace()
功能 : 设置初始断点,开始进入pdb调试模式
调试中的命令
break , b 设置断点
continue ,c 继续执行
w , 显示当前正在执行的代码行的上下文信息
list , l 查看当前代码段
next, n 单步执行
step, s 进入函数单步执行
pp 打印变量值
help 帮助
q 退出调试
exit 退出pdb调试
3. set 数据结构
交集:你可以对比两个集合的交集(两个集合中都有的数据)
set_a.intersection(set_b) : set_a和set_b共同拥有的元素,以set形式返回;
差集:你可以用差集(difference)找出无效的数据,相当于用一个集合减去另一个集合的数据
set_a.difference(set_b) : set_a减去set_b,相当于set_a单独拥有的元素,以set形式返回;
也可以用{}符号来创建集合,如:
a_set = {‘red‘, ‘blue‘, ‘green‘} print(type(a_set)) ### 输出: <type ‘set‘>
4. slots魔法方法
__slots__来告诉Python,当一个类需要创建大量实例时,可以通过__slots__声明实例所需要的属性,不要使用字典,而且只给一个固定集合的属性分配空间。
这样做带来以下优点:
默认情况下,访问一个实例的属性是通过访问该实例的__dict__来实现的。如访问a.x就相当于访问a.__dict__[‘x‘]。为了便于理解,我粗略地将它拆分为四步:
a.x 2. a.__dict__ 3. a.__dict__[‘x‘] 4. 结果
从__slots__的实现可以得知,定义了__slots__的类会为每个属性创建一个描述器。访问属性时就直接调用这个描述器。在这里我将它拆分为三步:
b.x 2. member decriptor 3. 结果
我在上文提到,访问__dict__和描述器的速度是相近的,而通过__dict__访问属性多了a.__dict__[‘x‘]字典访值一步(一个哈希函数的消耗)。由此可以推断出,使用了__slots__的类的属性访问速度比没有使用的要快。
[参考文章:Python__slots__详解 - rainfd - 博客园 https://www.cnblogs.com/rainfd/p/slots.html]
5. 容器数据类型 Collections
重点:
5.1 defaultdict :字典的子类,提供了一个工厂函数,为字典查询提供一个默认值;
文档:
1 Help on class defaultdict in module collections: 2 3 class defaultdict(builtins.dict) 4 5 | defaultdict(default_factory[, ...]) --> dict with default factory .The default factory is called without arguments to produce 6 7 | a new value when a key is not present, in __getitem__ only. A defaultdict compares equal to a dict with the same items. 8 9 | All remaining arguments are treated the same as if they were passed to the dict constructor, including keyword arguments. 10 11 | Method resolution order: 12 13 | defaultdict 14 15 | builtins.dict 16 17 | builtins.object 18 19 | Methods defined here: 20 21 | __copy__(...) 22 23 | D.copy() -> a shallow copy of D. 24 25 | __getattribute__(self, name, /) 26 27 | Return getattr(self, name). 28 29 | __init__(self, /, *args, **kwargs) 30 31 | Initialize self. See help(type(self)) for accurate signature. 32 33 | __missing__(...) 34 35 | __missing__(key) # Called by __getitem__ for missing key; pseudo-code: 36 37 | if self.default_factory is None: raise KeyError((key,)) 38 39 | self[key] = value = self.default_factory() 40 41 | return value 42 43 | __reduce__(...) 44 45 | Return state information for pickling. 46 47 | __repr__(self, /) 48 49 | Return repr(self). 50 51 | copy(...) 52 53 | D.copy() -> a shallow copy of D. 54 55 | ---------------------------------------------------------------------- 56 57 | Data descriptors defined here: 58 59 | default_factory 60 61 | Factory for default value called by __missing__(). 62 63 | ---------------------------------------------------------------------- 64 65 | Methods inherited from builtins.dict: 66 67 | __contains__(self, key, /) 68 69 | True if the dictionary has the specified key, else False. 70 71 | __delitem__(self, key, /) 72 73 | Delete self[key]. 74 75 | __eq__(self, value, /) 76 77 | Return self==value. 78 79 | __ge__(self, value, /) 80 81 | Return self>=value. 82 83 | __getitem__(...) 84 85 | x.__getitem__(y) <==> x[y] 86 87 | __gt__(self, value, /) 88 89 | Return self>value. 90 91 | __iter__(self, /) 92 93 | Implement iter(self). 94 95 | __le__(self, value, /) 96 97 | Return self<=value. 98 99 | __len__(self, /) 100 101 | Return len(self). 102 103 | __lt__(self, value, /) 104 105 | Return self<value. 106 107 | __ne__(self, value, /) 108 109 | Return self!=value. 110 111 | __setitem__(self, key, value, /) 112 113 | Set self[key] to value. 114 115 | __sizeof__(...) 116 117 | D.__sizeof__() -> size of D in memory, in bytes 118 119 | clear(...) 120 121 | D.clear() -> None. Remove all items from D. 122 123 | get(self, key, default=None, /) 124 125 | Return the value for key if key is in the dictionary, else default. 126 127 | items(...) 128 129 | D.items() -> a set-like object providing a view on D‘s items 130 131 | keys(...) 132 133 | D.keys() -> a set-like object providing a view on D‘s keys 134 135 | pop(...) 136 137 | D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 138 139 | If key is not found, d is returned if given, otherwise KeyError is raised 140 141 | popitem(...) 142 143 | D.popitem() -> (k, v), remove and return some (key, value) pair as a 144 145 | 2-tuple; but raise KeyError if D is empty. 146 147 | setdefault(self, key, default=None, /) 148 149 | Insert key with a value of default if key is not in the dictionary. 150 151 | Return the value for key if key is in the dictionary, else default. 152 153 | update(...) 154 155 | D.update([E, ]**F) -> None. Update D from dict/iterable E and F. 156 157 | If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] 158 159 | If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v 160 161 | In either case, this is followed by: for k in F: D[k] = F[k] 162 163 | values(...) 164 165 | D.values() -> an object providing a view on D‘s values 166 167 | ---------------------------------------------------------------------- 168 169 | Class methods inherited from builtins.dict: 170 171 | fromkeys(iterable, value=None, /) from builtins.type 172 173 | Create a new dictionary with keys from iterable and values set to value. 174 175 | ---------------------------------------------------------------------- 176 177 | Static methods inherited from builtins.dict: 178 179 | __new__(*args, **kwargs) from builtins.type 180 181 | Create and return a new object. See help(type) for accurate signature. 182 183 | ---------------------------------------------------------------------- 184 185 | Data and other attributes inherited from builtins.dict: 186 187 | __hash__ = None
与一般dict区别:标准字典包括setdefault方法()获取一个值,如果值不存在,建立一个默认;
相比之下,defaultdict允许调用者在初始化时预先设置默认值。
>>> from collections import defaultdict >>> dd = defaultdict(lambda: ‘N/A‘) >>> dd[‘key1‘] = ‘abc‘ >>> dd[‘key1‘] # key1存在 ‘abc‘ >>> dd[‘key2‘] # key2不存在,返回默认值 ‘N/A‘
使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict
注意:默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
5.2 Counter:字典的子类,提供了可哈希对象的计数功能
文档:
1 class Counter(builtins.dict) 2 3 | Counter(*args, **kwds) 4 5 | Dict subclass for counting hashable items. Sometimes called a bag 6 7 | or multiset. Elements are stored as dictionary keys and their counts 8 9 | are stored as dictionary values. 10 11 | >>> c = Counter(‘abcdeabcdabcaba‘) # count elements from a string 12 13 | >>> c.most_common(3) # three most common elements 14 15 | [(‘a‘, 5), (‘b‘, 4), (‘c‘, 3)] 16 17 | >>> sorted(c) # list all unique elements 18 19 | [‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘] 20 21 | >>> ‘‘.join(sorted(c.elements())) # list elements with repetitions 22 23 | ‘aaaaabbbbcccdde‘ 24 25 | >>> sum(c.values()) # total of all counts 26 27 | 15 28 29 | >>> c[‘a‘] # count of letter ‘a‘ 30 31 | 5 32 33 | >>> for elem in ‘shazam‘: # update counts from an iterable 34 35 | ... c[elem] += 1 # by adding 1 to each element‘s count 36 37 | >>> c[‘a‘] # now there are seven ‘a‘ 38 39 | 7 40 41 | >>> del c[‘b‘] # remove all ‘b‘ 42 43 | >>> c[‘b‘] # now there are zero ‘b‘ 44 45 | 0 46 47 | >>> d = Counter(‘simsalabim‘) # make another counter 48 49 | >>> c.update(d) # add in the second counter 50 51 | >>> c[‘a‘] # now there are nine ‘a‘ 52 53 | 9 54 55 | >>> c.clear() # empty the counter 56 57 | >>> c 58 59 | Counter() 60 61 | Note: If a count is set to zero or reduced to zero, it will remain 62 63 | in the counter until the entry is deleted or the counter is cleared: 64 65 | >>> c = Counter(‘aaabbc‘) 66 67 | >>> c[‘b‘] -= 2 # reduce the count of ‘b‘ by two 68 69 | >>> c.most_common() # ‘b‘ is still in, but its count is zero 70 71 | [(‘a‘, 3), (‘c‘, 1), (‘b‘, 0)] 72 73 | Method resolution order: 74 75 | Counter 76 77 | builtins.dict 78 79 | builtins.object 80 81 | Methods defined here: 82 83 | __add__(self, other) 84 85 | Add counts from two counters. 86 87 | >>> Counter(‘abbb‘) + Counter(‘bcc‘) 88 89 | Counter({‘b‘: 4, ‘c‘: 2, ‘a‘: 1}) 90 91 | __and__(self, other) 92 93 | Intersection is the minimum of corresponding counts. 94 95 | >>> Counter(‘abbb‘) & Counter(‘bcc‘) 96 97 | Counter({‘b‘: 1}) 98 99 | __delitem__(self, elem) 100 101 | Like dict.__delitem__() but does not raise KeyError for missing values. 102 103 | __iadd__(self, other) 104 105 | Inplace add from another counter, keeping only positive counts. 106 107 | >>> c = Counter(‘abbb‘) 108 109 | >>> c += Counter(‘bcc‘) 110 111 | >>> c 112 113 | Counter({‘b‘: 4, ‘c‘: 2, ‘a‘: 1}) 114 115 | __iand__(self, other) 116 117 | Inplace intersection is the minimum of corresponding counts. 118 119 | >>> c = Counter(‘abbb‘) 120 121 | >>> c &= Counter(‘bcc‘) 122 123 | >>> c 124 125 | Counter({‘b‘: 1}) 126 127 | __init__(*args, **kwds) 128 129 | Create a new, empty Counter object. And if given, count elements 130 131 | from an input iterable. Or, initialize the count from another mapping 132 133 | of elements to their counts. 134 135 | >>> c = Counter() # a new, empty counter 136 137 | >>> c = Counter(‘gallahad‘) # a new counter from an iterable 138 139 | >>> c = Counter({‘a‘: 4, ‘b‘: 2}) # a new counter from a mapping 140 141 | >>> c = Counter(a=4, b=2) # a new counter from keyword args 142 143 | __ior__(self, other) 144 145 | Inplace union is the maximum of value from either counter. 146 147 | >>> c = Counter(‘abbb‘) 148 149 | >>> c |= Counter(‘bcc‘) 150 151 | >>> c 152 153 | Counter({‘b‘: 3, ‘c‘: 2, ‘a‘: 1}) 154 155 | __isub__(self, other) 156 157 | Inplace subtract counter, but keep only results with positive counts. 158 159 | >>> c = Counter(‘abbbc‘) 160 161 | >>> c -= Counter(‘bccd‘) 162 163 | >>> c 164 165 | Counter({‘b‘: 2, ‘a‘: 1}) 166 167 | __missing__(self, key) 168 169 | The count of elements not in the Counter is zero. 170 171 | __neg__(self) 172 173 | Subtracts from an empty counter. Strips positive and zero counts, 174 175 | and flips the sign on negative counts. 176 177 | __or__(self, other) 178 179 | Union is the maximum of value in either of the input counters. 180 181 | >>> Counter(‘abbb‘) | Counter(‘bcc‘) 182 183 | Counter({‘b‘: 3, ‘c‘: 2, ‘a‘: 1}) 184 185 | __pos__(self) 186 187 | Adds an empty counter, effectively stripping negative and zero counts 188 189 | __reduce__(self) 190 191 | Helper for pickle. 192 193 | __repr__(self) 194 195 | Return repr(self). 196 197 | __sub__(self, other) 198 199 | Subtract count, but keep only results with positive counts. 200 201 | >>> Counter(‘abbbc‘) - Counter(‘bccd‘) 202 203 | Counter({‘b‘: 2, ‘a‘: 1}) 204 205 | copy(self) 206 207 | Return a shallow copy. 208 209 | elements(self) 210 211 | Iterator over elements repeating each as many times as its count. 212 213 | >>> c = Counter(‘ABCABC‘) 214 215 | >>> sorted(c.elements()) 216 217 | [‘A‘, ‘A‘, ‘B‘, ‘B‘, ‘C‘, ‘C‘] 218 219 | # Knuth‘s example for prime factors of 1836: 2**2 * 3**3 * 17**1 220 221 | >>> prime_factors = Counter({2: 2, 3: 3, 17: 1}) 222 223 | >>> product = 1 224 225 | >>> for factor in prime_factors.elements(): # loop over factors 226 227 | ... product *= factor # and multiply them 228 229 | >>> product 230 231 | 1836 232 233 | Note, if an element‘s count has been set to zero or is a negative 234 235 | number, elements() will ignore it. 236 237 | most_common(self, n=None) 238 239 | List the n most common elements and their counts from the most 240 241 | common to the least. If n is None, then list all element counts. 242 243 | >>> Counter(‘abcdeabcdabcaba‘).most_common(3) 244 245 | [(‘a‘, 5), (‘b‘, 4), (‘c‘, 3)] 246 247 | subtract(*args, **kwds) 248 249 | Like dict.update() but subtracts counts instead of replacing them. 250 251 | Counts can be reduced below zero. Both the inputs and outputs are 252 253 | allowed to contain zero and negative counts. 254 255 | Source can be an iterable, a dictionary, or another Counter instance. 256 257 | >>> c = Counter(‘which‘) 258 259 | >>> c.subtract(‘witch‘) # subtract elements from another iterable 260 261 | >>> c.subtract(Counter(‘watch‘)) # subtract elements from another counter 262 263 | >>> c[‘h‘] # 2 in which, minus 1 in witch, minus 1 in watch 264 265 | 0 266 267 | >>> c[‘w‘] # 1 in which, minus 1 in witch, minus 1 in watch 268 269 | -1 270 271 | update(*args, **kwds) 272 273 | Like dict.update() but add counts instead of replacing them. 274 275 | Source can be an iterable, a dictionary, or another Counter instance. 276 277 | >>> c = Counter(‘which‘) 278 279 | >>> c.update(‘witch‘) # add elements from another iterable 280 281 | >>> d = Counter(‘watch‘) 282 283 | >>> c.update(d) # add elements from another counter 284 285 | >>> c[‘h‘] # four ‘h‘ in which, witch, and watch 286 287 | 4 288 289 | ---------------------------------------------------------------------- 290 291 | Class methods defined here: 292 293 | fromkeys(iterable, v=None) from builtins.type 294 295 | Create a new dictionary with keys from iterable and values set to value. 296 297 | ---------------------------------------------------------------------- 298 299 | Data descriptors defined here: 300 301 | __dict__ 302 303 | dictionary for instance variables (if defined) 304 305 | __weakref__ 306 307 | list of weak references to the object (if defined) 308 309 | ---------------------------------------------------------------------- 310 311 | Methods inherited from builtins.dict: 312 313 | __contains__(self, key, /) 314 315 | True if the dictionary has the specified key, else False. 316 317 | __eq__(self, value, /) 318 319 | Return self==value. 320 321 | __ge__(self, value, /) 322 323 | Return self>=value. 324 325 | __getattribute__(self, name, /) 326 327 | Return getattr(self, name). 328 329 | __getitem__(...) 330 331 | x.__getitem__(y) <==> x[y] 332 333 | __gt__(self, value, /) 334 335 | Return self>value. 336 337 | __iter__(self, /) 338 339 | Implement iter(self). 340 341 | __le__(self, value, /) 342 343 | Return self<=value. 344 345 | __len__(self, /) 346 347 | Return len(self). 348 349 | __lt__(self, value, /) 350 351 | Return self<value. 352 353 | __ne__(self, value, /) 354 355 | Return self!=value. 356 357 | __setitem__(self, key, value, /) 358 359 | Set self[key] to value. 360 361 | __sizeof__(...) 362 363 | D.__sizeof__() -> size of D in memory, in bytes 364 365 | clear(...) 366 367 | D.clear() -> None. Remove all items from D. 368 369 | get(self, key, default=None, /) 370 371 | Return the value for key if key is in the dictionary, else default. 372 373 | items(...) 374 375 | D.items() -> a set-like object providing a view on D‘s items 376 377 | keys(...) 378 379 | D.keys() -> a set-like object providing a view on D‘s keys 380 381 | 382 383 | pop(...) 384 385 | D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 386 387 | If key is not found, d is returned if given, otherwise KeyError is raised 388 389 | popitem(...) 390 391 | D.popitem() -> (k, v), remove and return some (key, value) pair as a 392 393 | 2-tuple; but raise KeyError if D is empty. 394 395 | setdefault(self, key, default=None, /) 396 397 | Insert key with a value of default if key is not in the dictionary. 398 399 | Return the value for key if key is in the dictionary, else default. 400 401 | values(...) 402 403 | D.values() -> an object providing a view on D‘s values 404 405 | ---------------------------------------------------------------------- 406 407 | Static methods inherited from builtins.dict: 408 409 | __new__(*args, **kwargs) from builtins.type 410 411 | Create and return a new object. See help(type) for accurate signature. 412 413 | ---------------------------------------------------------------------- 414 415 | Data and other attributes inherited from builtins.dict: 416 417 | __hash__ = None
from collections import Counter
Counter是一个简单的计数器,例如,统计字符出现的个数,空的Counter容器可以无参数构造,并采用update()方法进行更新;
most_common()返回前n个最多的数据,counter.most_common(x)返回前x个最多的数据;
Counter实例支持聚合结果的算术和集合操作;
elements()方法可以返回一个包含所有Counter数据的迭代器,counter.elements()。
5.3 deque 双端队列 :
文档:
1 class deque(builtins.object) 2 3 | deque([iterable[, maxlen]]) --> deque object 4 5 | A list-like sequence optimized for data accesses near its endpoints. 6 7 | Methods defined here: 8 9 | __add__(self, value, /) 10 11 | Return self+value. 12 13 | __bool__(self, /) 14 15 | self != 0 16 17 | __contains__(self, key, /) 18 19 | Return key in self. 20 21 | __copy__(...) 22 23 | Return a shallow copy of a deque. 24 25 | __delitem__(self, key, /) 26 27 | Delete self[key]. 28 29 | __eq__(self, value, /) 30 31 | Return self==value. 32 33 | __ge__(self, value, /) 34 35 | Return self>=value. 36 37 | __getattribute__(self, name, /) 38 39 | Return getattr(self, name). 40 41 | __getitem__(self, key, /) 42 43 | Return self[key]. 44 45 | __gt__(self, value, /) 46 47 | Return self>value. 48 49 | __iadd__(self, value, /) 50 51 | Implement self+=value. 52 53 | __imul__(self, value, /) 54 55 | Implement self*=value. 56 57 | __init__(self, /, *args, **kwargs) 58 59 | Initialize self. See help(type(self)) for accurate signature. 60 61 | __iter__(self, /) 62 63 | Implement iter(self). 64 65 | __le__(self, value, /) 66 67 | Return self<=value. 68 69 | __len__(self, /) 70 71 | Return len(self). 72 73 | __lt__(self, value, /) 74 75 | Return self<value. 76 77 | __mul__(self, value, /) 78 79 | Return self*value. 80 81 | __ne__(self, value, /) 82 83 | Return self!=value. 84 85 | __reduce__(...) 86 87 | Return state information for pickling. 88 89 | __repr__(self, /) 90 91 | Return repr(self). 92 93 | __reversed__(...) 94 95 | D.__reversed__() -- return a reverse iterator over the deque 96 97 | __rmul__(self, value, /) 98 99 | Return value*self. 100 101 | __setitem__(self, key, value, /) 102 103 | Set self[key] to value. 104 105 | __sizeof__(...) 106 107 | D.__sizeof__() -- size of D in memory, in bytes 108 109 | append(...) 110 111 | Add an element to the right side of the deque. 112 113 | appendleft(...) 114 115 | Add an element to the left side of the deque. 116 117 | clear(...) 118 119 | Remove all elements from the deque. 120 121 | copy(...) 122 123 | Return a shallow copy of a deque. 124 125 | count(...) 126 127 | D.count(value) -> integer -- return number of occurrences of value 128 129 | 130 131 | extend(...) 132 133 | Extend the right side of the deque with elements from the iterable 134 135 | extendleft(...) 136 137 | Extend the left side of the deque with elements from the iterable 138 139 | index(...) 140 141 | D.index(value, [start, [stop]]) -> integer -- return first index of value. 142 143 | Raises ValueError if the value is not present. 144 145 | insert(...) 146 147 | D.insert(index, object) -- insert object before index 148 149 | pop(...) 150 151 | Remove and return the rightmost element. 152 153 | popleft(...) 154 155 | Remove and return the leftmost element. 156 157 | remove(...) 158 159 | D.remove(value) -- remove first occurrence of value. 160 161 | reverse(...) 162 163 | D.reverse() -- reverse *IN PLACE* 164 165 | rotate(...) 166 167 | Rotate the deque n steps to the right (default n=1). If n is negative, rotates left. 168 169 | ---------------------------------------------------------------------- 170 171 | Static methods defined here: 172 173 | __new__(*args, **kwargs) from builtins.type 174 175 | Create and return a new object. See help(type) for accurate signature. 176 177 | ---------------------------------------------------------------------- 178 179 | Data descriptors defined here: 180 181 | maxlen 182 183 | maximum size of a deque or None if unbounded 184 185 | ---------------------------------------------------------------------- 186 187 | Data and other attributes defined here: 188 189 | __hash__ = None
类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop),deque是为了高效实现插入和删除操作的双向列表,适合用于
队列和栈, deque除了实现list的append()和pop()外,还支持左端插入appendleft()和左端删除popleft(),这样就可以非常高效地往头部添加或 删除元素。
由于双端队列是线程安全的,在单独的线程中内容甚至可以从两端同时消费。
5.4 namedtuple 命名元组 :创建命名元组子类的工厂函数
文档:
1 Help on function namedtuple in module collections: 2 3 namedtuple(typename, field_names, *, rename=False, defaults=None, module=None) 4 5 Returns a new subclass of tuple with named fields. 6 7 >>> Point = namedtuple(‘Point‘, [‘x‘, ‘y‘]) 8 9 >>> Point.__doc__ # docstring for the new class 10 11 ‘Point(x, y)‘ 12 13 >>> p = Point(11, y=22) # instantiate with positional args or keywords >>> p[0] + p[1] # indexable 14 15 like a plain tuple 16 17 33 18 19 >>> x, y = p # unpack like a regular tuple 20 21 >>> x, y 22 23 (11, 22) 24 25 >>> p.x + p.y # fields also accessible by name 26 27 33 28 29 >>> d = p._asdict() # convert to a dictionary 30 31 >>> d[‘x‘] 32 33 11 34 35 >>> Point(**d) # convert from a dictionary 36 37 Point(x=11, y=22) 38 39 >>> p._replace(x=100) # _replace() is like str.replace() but targets named fields 40 41 Point(x=100, y=22)
from collections import namedtuple
用法: namedtuple(‘名称‘, [属性list]):
Circle = namedtuple(‘Circle‘, [‘x‘, ‘y‘, ‘r‘])
命名元组(namedtuple)有两个必需的参数。 它们是元组名称和字段名称。 namedtuple的每个实例没有对象字典,所以它们很轻量,与普通的元组相比,并不需要更多的内存。这使得它们比字典更快。属性值在namedtuple中是不可变的,
namedtuple向后兼容于普通的元组,可以既使用整数索引,也可以使用名称来访问namedtuple
._asdict()方法将一个命名元组转换为字典,用法:namedtuple._asdict()
5.5 OrderedDict :字典的子类,保存了他们被添加的顺序
文档:
1 Help on class OrderedDict in module collections: 2 3 class OrderedDict(builtins.dict) 4 5 | Dictionary that remembers insertion order 6 7 | 8 9 | Method resolution order: 10 11 | OrderedDict 12 13 | builtins.dict 14 15 | builtins.object 16 17 | 18 19 | Methods defined here: 20 21 | 22 23 | __delitem__(self, key, /) 24 25 | Delete self[key]. 26 27 | 28 29 | __eq__(self, value, /) 30 31 | Return self==value. 32 33 | 34 35 | __ge__(self, value, /) 36 37 | Return self>=value. 38 39 | 40 41 | __gt__(self, value, /) 42 43 | Return self>value. 44 45 | 46 47 | __init__(self, /, *args, **kwargs) 48 49 | Initialize self. See help(type(self)) for accurate signature. 50 51 | 52 53 | __iter__(self, /) 54 55 | Implement iter(self). 56 57 | 58 59 | __le__(self, value, /) 60 61 | Return self<=value. 62 63 | 64 65 | __lt__(self, value, /) 66 67 | Return self<value. 68 69 | 70 71 | __ne__(self, value, /) 72 73 | Return self!=value. 74 75 | 76 77 | __reduce__(...) 78 79 | Return state information for pickling 80 81 | 82 83 | __repr__(self, /) 84 85 | Return repr(self). 86 87 | 88 89 | __reversed__(...) 90 91 | od.__reversed__() <==> reversed(od) 92 93 | 94 95 | __setitem__(self, key, value, /) 96 97 | Set self[key] to value. 98 99 | 100 101 | __sizeof__(...) 102 103 | D.__sizeof__() -> size of D in memory, in bytes 104 105 | 106 107 | clear(...) 108 109 | od.clear() -> None. Remove all items from od. 110 111 | 112 113 | copy(...) 114 115 | od.copy() -> a shallow copy of od 116 117 | 118 119 | items(...) 120 121 | D.items() -> a set-like object providing a view on D‘s items 122 123 | 124 125 | keys(...) 126 127 | D.keys() -> a set-like object providing a view on D‘s keys 128 129 | 130 131 | move_to_end(self, /, key, last=True) 132 133 | Move an existing element to the end (or beginning if last is false). 134 135 | 136 137 | Raise KeyError if the element does not exist. 138 139 | 140 141 | pop(...) 142 143 | od.pop(k[,d]) -> v, remove specified key and return the corresponding 144 145 | value. If key is not found, d is returned if given, otherwise KeyError 146 147 | is raised. 148 149 | 150 151 | popitem(self, /, last=True) 152 153 | Remove and return a (key, value) pair from the dictionary. 154 155 | 156 157 | Pairs are returned in LIFO order if last is true or FIFO order if false. 158 159 | 160 161 | setdefault(self, /, key, default=None) 162 163 | Insert key with a value of default if key is not in the dictionary. 164 165 | 166 167 | Return the value for key if key is in the dictionary, else default. 168 169 | 170 171 | update(...) 172 173 | D.update([E, ]**F) -> None. Update D from dict/iterable E and F. 174 175 | If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] 176 177 | If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v 178 179 | In either case, this is followed by: for k in F: D[k] = F[k] 180 181 | 182 183 | values(...) 184 185 | D.values() -> an object providing a view on D‘s values 186 187 | 188 189 | ---------------------------------------------------------------------- 190 191 | Class methods defined here: 192 193 | 194 195 | fromkeys(iterable, value=None) from builtins.type 196 197 | Create a new ordered dictionary with keys from iterable and values set to value. 198 199 | 200 201 | ---------------------------------------------------------------------- 202 203 | Data descriptors defined here: 204 205 | 206 207 | __dict__ 208 209 | 210 211 | ---------------------------------------------------------------------- 212 213 | Data and other attributes defined here: 214 215 | 216 217 | __hash__ = None 218 219 | 220 221 | ---------------------------------------------------------------------- 222 223 | Methods inherited from builtins.dict: 224 225 | 226 227 | __contains__(self, key, /) 228 229 | True if the dictionary has the specified key, else False. 230 231 | 232 233 | __getattribute__(self, name, /) 234 235 | Return getattr(self, name). 236 237 | 238 239 | __getitem__(...) 240 241 | x.__getitem__(y) <==> x[y] 242 243 | 244 245 | __len__(self, /) 246 247 | Return len(self). 248 249 | 250 251 | get(self, key, default=None, /) 252 253 | Return the value for key if key is in the dictionary, else default. 254 255 | 256 257 | ---------------------------------------------------------------------- 258 259 | Static methods inherited from builtins.dict: 260 261 | 262 263 | __new__(*args, **kwargs) from builtins.type 264 265 | Create and return a new object. See help(type) for accurate signature.
使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict:
from collections import OrderedDict
OrderedDict 内部维护着一个根据键插入顺序排序的双向链表。每次当一个新的元素插入进来的时候,它会被放到链表的尾部。对于一个已经存在的键的重复赋值不会改变键的顺序。
OrderedDict的Key会按照插入的顺序排列,不是Key本身排序,即OrderedDict可以实现一个FIFO(先进先出)的dict,当容量超出限制时,先删除最早添加的Key。
需要注意的是,一个 OrderedDict 的大小是一个普通字典的两倍,因为它内部维护着另外一个链表。 所以如果你要构建一个需要大量OrderedDict实例的数据结构的时候(比如读取 100,000 行 CSV 数据到一个 OrderedDict 列表中去), 那么你就得仔细权衡一下是否使用 OrderedDict 带来的好处要大过额外内存消耗的影响。
【参考:1.7 字典排序 — python3-cookbook 3.0.0 文档 https://python3-cookbook.readthedocs.io
python标准库之collections介绍 - luminousjj - 博客园 https://www.cnblogs.com/luminousjj/p/9342161.html】
6. Python itertools库:Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。
[参考文章:Python标准库之itertools库的使用方法_python_脚本之家 https://www.jb51.net/article/123094.htm]
itertools中的函数大多是返回各种迭代器对象,其中很多函数的作用我们平时要写很多代码才能达到,而在运行效率上反而更低,毕竟人家是系统库。
itertools.accumulate
简单来说就是累加。
>>> import itertools >>> x = itertools.accumulate(range(10)) >>> print(list(x)) [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]
itertools.chain
连接多个列表或者迭代器。
>>> x = itertools.chain(range(3), range(4), [3,2,1]) >>> print(list(x)) [0, 1, 2, 0, 1, 2, 3, 3, 2, 1]
itertools.combinations
求列表或生成器中指定数目的元素不重复的所有组合
>>> x = itertools.combinations(range(4), 3) >>> print(list(x)) [(0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3)]
itertools.combinations_with_replacement
允许重复元素的组合
>>> x = itertools.combinations_with_replacement(‘ABC‘, 2) >>> print(list(x)) [(‘A‘, ‘A‘), (‘A‘, ‘B‘), (‘A‘, ‘C‘), (‘B‘, ‘B‘), (‘B‘, ‘C‘), (‘C‘, ‘C‘)]
itertools.compress
按照真值表筛选元素
>>> x = itertools.compress(range(5), (True, False, True, True, False)) >>> print(list(x)) [0, 2, 3]
itertools.count
就是一个计数器,可以指定起始位置和步长
>>> x = itertools.count(start=20, step=-1) >>> print(list(itertools.islice(x, 0, 10, 1))) [20, 19, 18, 17, 16, 15, 14, 13, 12, 11]
itertools.cycle
循环指定的列表和迭代器
>>> x = itertools.cycle(‘ABC‘) >>> print(list(itertools.islice(x, 0, 10, 1))) [‘A‘, ‘B‘, ‘C‘, ‘A‘, ‘B‘, ‘C‘, ‘A‘, ‘B‘, ‘C‘, ‘A‘]
itertools.dropwhile
按照真值函数丢弃掉列表和迭代器前面的元素
>>> x = itertools.dropwhile(lambda e: e < 5, range(10)) >>> print(list(x)) [5, 6, 7, 8, 9]
itertools.filterfalse
保留对应真值为False的元素
>>> x = itertools.filterfalse(lambda e: e < 5, (1, 5, 3, 6, 9, 4)) >>> print(list(x)) [5, 6, 9]
itertools.groupby
按照分组函数的值对元素进行分组
>>> x = itertools.groupby(range(10), lambda x: x < 5 or x > 8) >>> for condition, numbers in x: ... print(condition, list(numbers)) True [0, 1, 2, 3, 4] False [5, 6, 7, 8] True [9]
itertools.islice(下面有详细介绍)
上文使用过的函数,对迭代器进行切片
>>> x = itertools.islice(range(10), 0, 9, 2) >>> print(list(x)) [0, 2, 4, 6, 8]
itertools.permutations
产生指定数目的元素的所有排列(顺序有关)
>>> x = itertools.permutations(range(4), 3) >>> print(list(x)) [(0, 1, 2), (0, 1, 3), (0, 2, 1), (0, 2, 3), (0, 3, 1), (0, 3, 2), (1, 0, 2), (1, 0, 3), (1, 2, 0), (1, 2, 3), (1, 3, 0), (1, 3, 2), (2, 0, 1), (2, 0, 3), (2, 1, 0), (2, 1, 3), (2, 3, 0), (2, 3, 1), (3, 0, 1), (3, 0, 2), (3, 1, 0), (3, 1, 2), (3, 2, 0), (3, 2, 1)]
itertools.product
产生多个列表和迭代器的(积)
>>> x = itertools.product(‘ABC‘, range(3)) >>> >>> print(list(x)) [(‘A‘, 0), (‘A‘, 1), (‘A‘, 2), (‘B‘, 0), (‘B‘, 1), (‘B‘, 2), (‘C‘, 0), (‘C‘, 1), (‘C‘, 2)]
itertools.repeat
简单的生成一个拥有指定数目元素的迭代器
>>> x = itertools.repeat(0, 5) >>> print(list(x)) [0, 0, 0, 0, 0]
itertools.starmap
类似map
>>> x = itertools.starmap(str.islower, ‘aBCDefGhI‘) >>> print(list(x)) [True, False, False, False, True, True, False, True, False]
itertools.takewhile
与dropwhile相反,保留元素直至真值函数值为假。
>>> x = itertools.takewhile(lambda e: e < 5, range(10)) >>> print(list(x)) [0, 1, 2, 3, 4]
itertools.tee
这个函数我也不是很懂,似乎是生成指定数目的迭代器
>>> x = itertools.tee(range(10), 2) >>> for letters in x: ... print(list(letters)) ... [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
itertools.zip_longest
类似于zip,不过已较长的列表和迭代器的长度为准
>>> x = itertools.zip_longest(range(3), range(5)) >>> y = zip(range(3), range(5)) >>> print(list(x)) [(0, 0), (1, 1), (2, 2), (None, 3), (None, 4)] >>> print(list(y)) [(0, 0), (1, 1), (2, 2)]
7. 推导式 Comprehension ,可迭代对象 Iterable,迭代器 Iterator 及 生成器 Generators
7.1 推导式
推导式一般用的最多的是列表推导式(list comprehensions)
example:a = [i*i for i in range(10)]
官方解释:列表解析式是Python内置的非常简单却强大的可以用来创建list的生成式,在一个中括号里包含一个表达式, 然后是一个for语句, 然后是0个或多个for或者if语句。 那个表达式可以是任意的, 意思是你可以在列表中放任意类型的对象。返回结果将是一个新的列表,在这个以if和for语句为上下文的表达式运行完成之后产生。
可以看到,使用列表解析式的写法更加简短,除此之外,因为是Python内置的用法,底层使用c语言实现,相较于编写Python代码而言,运行速度更快。
====总结====:如果要对现有可迭代对象做一下处理,然后生成新的列表,使用列表推导式将是最便捷的方法。
7.2 可迭代对象 Iterable
最简单的解释:可以使用for...in...语句进行循环的对象,就是可迭代对象(Iterable),可以使用isinstance()方法进行判断。list、dict、str是Iterable(可迭代对象),但不是Iterator(迭代器),可以使用iter()函数把list、dict、str等Iterable变成Iterator。
temp=iter([1, 2, 3]) print type(temp) # list_iterator print next(temp) # 1
7.3 迭代器 Iterator
任意对象,只要定义了next (Python2) 或者__next__方法并实现了iter方法,它就是一个迭代器。
迭代器的优势:在构建迭代器时,不是将所有元素一次性的加载,而是等调用next方法时返回元素,大量节省内存。
迭代器应用场景:数列的数据规模巨大且数列有规律,但是不能使用列表推导式描述的时候,如大数据量的数列的创建,大文件的读取等。
7.4 生成器 Generators
生成器是一个特殊的函数,可以被用作控制循环的迭代行为,python中生成器是一种高级迭代器,使用yield代替return返回,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
生成器类似于返回值为一个数组的一个函数,这个函数可以接收参数,可以被调用,但是不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,生成器可以被看作是一个函数,但是它本质上也算是一个迭代器。
生成器函数:为什么叫生成器函数?因为它随着时间的推移生成了一个数值队列。一般的函数在执行完毕之后会返回一个值然后退出,但是生成器函数会自动挂起,然后重新拾起急需执行,利用yield关键字关起函数,给调用者返回一个值,同时保留了当前的足够多的状态,可以使函数继续执行。当需要一个将返回一个序列或在循环中执行的函数时,就可以使用生成器,因为当这些元素被传递到另一个函数中进行后续处理时,一次返回一个元素可以有效的提升整体性能。常见的应用场景是使用生成器生成数据流缓冲区。
生成器表达式:生成式表达式是一种实现生成器的便捷方式,将列表推导式的中括号替换为圆括号。返回一个对象,这个对象只有在需要的时候才产生结果。
生成器表达式的一个例子: g = (x*x for x in range(10))
[参考文章]:
python 生成器和迭代器有这篇就够了 - 战争热诚 - 博客园 https://www.cnblogs.com/wj-1314/p/8490822.html
迭代器 生成器, 可迭代对象以及应用场景 - 若无过客丶何来人生 - 博客园 https://www.cnblogs.com/liurenli/p/10127818.html
8. 命名切片
slice() 函数 描述:slice() 函数用实现切片对象,主要在切片操作函数里的参数传递。
slice 语法:
class slice(stop)
class slice(start, stop[, step])
如果你有一个切片对象 a,你可以分别调用它的 a.start , a.stop , a.step 属性来获取更多的信息。
另外,你还能通过调用切片的 indices(size) 方法将它映射到一个确定大小的序列上,这个方法返回一个三元组 (start, stop, step) ,所有值都会被合适的缩小以满足边界限制,从而使用的时候避免出现 IndexError 异常。
文档的说明:
1 class slice(object) 2 3 | slice(stop) 4 5 | slice(start, stop[, step]) 6 7 | Create a slice object. This is used for extended slicing (e.g. a[0:10:2]). 8 9 | Methods defined here: 10 11 | __eq__(self, value, /) 12 13 | Return self==value. 14 15 | __ge__(self, value, /) 16 17 | Return self>=value. 18 19 | 20 21 | __getattribute__(self, name, /) 22 23 | Return getattr(self, name). 24 25 | __gt__(self, value, /) 26 27 | Return self>value. 28 29 | __le__(self, value, /) 30 31 | Return self<=value. 32 33 | __lt__(self, value, /) 34 35 | Return self<value. 36 37 | __ne__(self, value, /) 38 39 | Return self!=value. 40 41 | __reduce__(...) 42 43 | Return state information for pickling. 44 45 | __repr__(self, /) 46 47 | Return repr(self). 48 49 | indices(...) 50 51 | S.indices(len) -> (start, stop, stride) 52 53 | Assuming a sequence of length len, calculate the start and stop 54 55 | indices, and the stride length of the extended slice described by 56 57 | S. Out of bounds indices are clipped in a manner consistent with the 58 59 | handling of normal slices. 60 61 | ---------------------------------------------------------------------- 62 63 | Static methods defined here: 64 65 | __new__(*args, **kwargs) from builtins.type 66 67 | Create and return a new object. See help(type) for accurate signature.-- More -- | 68 69 | ---------------------------------------------------------------------- 70 71 | Data descriptors defined here: 72 73 | start 74 75 | step 76 77 | stop 78 79 | ---------------------------------------------------------------------- 80 81 | Data and other attributes defined here: 82 83 | __hash__ = None
9. 上下文管理器:
常见用法:
with open(‘test.txt‘) as f:
print f.readlines()
几个概念
为什么要使用上下文管理器?
简单点说,就是在一个类里,实现了__enter__和__exit__的方法,这个类的实例就是一个上下文管理器。
一个基管于类实现的上下文理器:
class File(object):
def __init__(self, file_name, method):
self.file_obj = open(file_name, method)
def __enter__(self):
return self.file_obj
def __exit__(self, exc_type, exc_value, exc_traceback):
self.file_obj.close()
注:exc_type:异常类型 , exc_value:异常值, exc_traceback:异常的错误栈信息
执行过程:
with语句先暂存了File类的__exit__方法;
然后它调用File类的__enter__方法;
__enter__方法打开文件并返回给with语句;
打开的文件句柄被传递给opened_file参数;
我们使用.write()来写文件;
with语句调用之前暂存的__exit__方法;
__exit__方法关闭了文件。
[关于上下文管理器的更多详细可以参考文章]:
浅淡python中with的用法,上下文管理器 - 听风。 - 博客园 https://www.cnblogs.com/huchong/p/8268765.html
深入理解 Python 中的上下文管理器 - 王一白 - 博客园 https://www.cnblogs.com/wongbingming/p/10519553.html
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,如果有哪些问题、有些谬误、有哪些不妥或者侵犯到您的权益的地方,可以联系我,我马上修改。
[Python进阶]Python builtin 函数及重要知识点学习笔记(一)
原文:https://www.cnblogs.com/vanjoe/p/12822280.html