Python学习笔记-3
enumerate用法
enumerate()
是python的内置函数,在字典上是枚举、列举的意思。enumerate
参数为可遍历/可迭代的对象(如列表、字符串),多用于在for循环中得到计数,利用它可以同时获得索引和值,即需要index和value值的时候可以使用enumerate
。
>>> lst = [1, 2, 3, 4, 10, 5]
>>> enumerate(lst)
<enumerate object at 0x00000000032A3990>
enumerate的使用:
>>> lst = [1,2,3,4,5,6]
>>> for index,value in enumerate(lst):
print ('%s,%s' % (index,value))
0,1
1,2
2,3
3,4
4,5
5,6
#指定索引从1开始
>>> lst = [1,2,3,4,5,6]
>>> for index,value in enumerate(lst,1):
print ('%s,%s' % (index,value))
1,1
2,2
3,3
4,4
5,5
6,6
#指定索引从3开始
>>> for index,value in enumerate(lst,3):
print ('%s,%s' % (index,value))
3,1
4,2
5,3
6,4
7,5
8,6
如果要统计文件的行数,可以这样写:
count = len(open(filepath, 'r').readlines())
这种方法简单,但是可能比较慢,当文件比较大时甚至不能工作。
可以利用enumerate():
count = 0
for index, line in enumerate(open(filepath,'r')):
count += 1
注:enumerate的用法转自博客
heapq模块
-
heapq.heappush(heap, item)
heap为堆(列表),item增加的元素。跟
list.append(item)
作用一样
>>> import heapq
>>> h = []
>>> heapq.heappush(h, 1)
>>> heapq.heappush(h, 3)
>>> h
[1, 3]
-
heapq.heapify(list)
将列表转换为堆
>>> list = [1, 3, 5, 8, 4, 2 ] >>> heapq.heapify(list) >>> list [1, 3, 2, 8, 4, 5]
-
heapq.heappop(heap)
删除并返回最小值,因为
heap
第一个元素永远是最小值,所以其实就是弹出第一个元素。 -
heapq.heapreplace(heap, item)
删除返回最小值,并将新的元素
item
添加进去。 -
heapq.heappushpop(heap, item)
添加的元素若大于
heap
的最小值,则弹出最小值并添加item
。否则,直接返回item
,不进行替换。 -
heapq.merge(heap1, heap2)
合并最小堆
-
heapq.nlargest()
和heapq.nsmallest()
从列表中找出最大的或最小的N个元素。
import heapq list1 = [34, 25, 12, 99, 87, 63, 58, 78, 88, 92] list2 = [ {'name': 'IBM', 'shares': 100, 'price': 91.1}, {'name': 'AAPL', 'shares': 50, 'price': 543.22}, {'name': 'FB', 'shares': 200, 'price': 21.09}, {'name': 'HPQ', 'shares': 35, 'price': 31.75}, {'name': 'YHOO', 'shares': 45, 'price': 16.35}, {'name': 'ACME', 'shares': 75, 'price': 115.65} ] print(heapq.nlargest(3, list1)) print(heapq.nsmallest(3, list1)) print(heapq.nlargest(2, list2, key=lambda x: x['price'])) print(heapq.nlargest(2, list2, key=lambda x: x['shares']))
itertools模块
itertools
模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是Iterator
,只有用for
循环迭代的时候才真正计算。
-
itertools.count
cout()
会创建一个无限的迭代器,后续只能通过Ctrl+C
来停止。输入的只能是数字,不一定要从1开始。>>> natuals = itertools.count(2) >>> for n in natuals: ... print(n) ... 2 3 4 5
-
itertools.cycle()
cycle
会创建一个无限的迭代器,会把传入的一个序列无限重复下去。>>> import itertools >>> list = [1, 3, 5, 7, 9] >>> list_iter = itertools.cycle(list) >>> for i in list_iter: ... print(i) ... 1 3 5 7 9 1
-
itertools.repeat(item, num)
repeat()
负责把一个元素无限重复下去,如果提供第二个参数num
就可以限定重复次数。>>> list = itertools.repeat('A', 4) >>> for i in list: ... print(i) ... A A A A
-
itertools.chain(iter1, iter2)
将迭代对象连接起来,形成新的迭代器。
>>> for i in itertools.chain('ABC', 'EFG'): ... print(i) ... A B C E F G
-
itertools.combinations(iter, num)
在
iter
中进行选择num
个元素的组合。>>> for i in itertools.combinations('ABCDE', 3): ... print(i) ... ('A', 'B', 'C') ('A', 'B', 'D') ('A', 'B', 'E') ('A', 'C', 'D') ('A', 'C', 'E') ('A', 'D', 'E') ('B', 'C', 'D') ('B', 'C', 'E') ('B', 'D', 'E') ('C', 'D', 'E')
-
itertools
还有很多函数,其他的还是自己查资料吧。
Collections模块
-
namedtuple
我们知道
tuple
可以表示不变集合,例如,一个点的二维坐标就可以表示成:
>>> p = (1, 2)
但是,看到(1, 2)
,很难看出这个tuple
是用来表示一个坐标的。
>>> from collections import namedtuple
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(1, 2)
>>> p.x
1
>>> p.y
2
namedtuple
是一个函数,它用来创建一个自定义的tuple
对象,并且规定了tuple
元素的个数,并可以用属性而不是索引来引用tuple
的某个元素。用namedtuple
可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。可以验证创建的Point
对象是tuple
的一种子类:
>>> isinstance(p, Point)
True
>>> isinstance(p, tuple)
True
类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple
定义:
# namedtuple('名称', [属性list]):
Circle = namedtuple('Circle', ['x', 'y', 'r'])
- deque
使用list
存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list
是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
>>> from collections import deque
>>> q = deque(['a', 'b', 'c'])
>>> q.append('x')
>>> q.appendleft('y')
>>> q
deque(['y', 'a', 'b', 'c', 'x'])
deque
除了实现list的append()
和pop()
外,还支持appendleft()
和popleft()
,这样就可以非常高效地往头部添加或删除元素。append()
是右插入,appendleft()
是左插入。
- defaultdict
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
>>> from collections import defaultdict
>>> dd = defaultdict(lambda: 'N/A')
>>> dd['key1'] = 'abc'
>>> dd['key1'] # key1存在
'abc'
>>> dd['key2'] # key2不存在,返回默认值
'N/A'
注意默认值是调用函数返回的,而函数在创建defaultdict
对象时传入。
除了在Key不存在时返回默认值,defaultdict
的其他行为跟dict
是完全一样的。
- OrderedDict
使用dict
时,Key是无序的。在对dict
做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
>>> from collections import OrderedDict
>>> d = dict([('a', 1), ('b', 2), ('c', 3)])
>>> d # dict的Key是无序的
{'a': 1, 'c': 3, 'b': 2}
>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
>>> od # OrderedDict的Key是有序的
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序:
>>> od = OrderedDict()
>>> od['z'] = 1
>>> od['y'] = 2
>>> od['x'] = 3
>>> list(od.keys()) # 按照插入的Key的顺序返回
['z', 'y', 'x']
- ChainMap
ChainMap
可以把一组dict
串起来并组成一个逻辑上的dict
。ChainMap
本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
问题的背景是我们有多个字典或者映射,想把它们合并成为一个单独的映射,有人说可以用update进行合并,这样做的问题就是新建了一个数据结构以致于当我们对原来的字典进行更改的时候不会同步。如果想建立一个同步的查询方法,可以使用ChainMap
先看一下初步使用
from collections import ChainMapa = {"x":1, "z":3}
b = {"y":2, "z":4}
c = ChainMap(a,b)
print(c)
print("x: {}, y: {}, z: {}".format(c["x"], c["y"], c["z"]))
输出:
ChainMap({'x': 1, 'z': 3}, {'y': 2, 'z': 4})
x: 1, y: 2, z: 3
[Finished in 0.1s]
这是ChainMap最基本的使用,可以用来合并两个或者更多个字典,当查询的时候,从前往后依次查询。
有一个注意点就是当对ChainMap进行修改的时候总是只会对第一个字典进行修改
In [6]: a = {"x":1, "z":3}
In [7]: b = {"y":2, "z":4}
In [8]: c = ChainMap(a, b)
In [9]: c
Out[9]: ChainMap({'z': 3, 'x': 1}, {'z': 4, 'y': 2})
In [10]: c["z"]
Out[10]: 3
In [11]: c["z"] = 4
In [12]: c
Out[12]: ChainMap({'z': 4, 'x': 1}, {'z': 4, 'y': 2})
In [13]: c.pop('z')
Out[13]: 4
In [14]: c
Out[14]: ChainMap({'x': 1}, {'z': 4, 'y': 2})
In [15]: del c["y"]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
。。。。。。
KeyError: "Key not found in the first mapping: 'y'"
- Counter
Counter
是一个简单的计数器,例如,统计字符出现的个数:
>>> from collections import Counter
>>> c = Counter()
>>> for ch in 'programming':
... c[ch] = c[ch] + 1
...
>>> c
Counter({'g': 2, 'm': 2, 'r': 2, 'a': 1, 'i': 1, 'o': 1, 'n': 1, 'p': 1})
>>> c.update('hello') # 也可以一次性update
>>> c
Counter({'r': 2, 'o': 2, 'g': 2, 'm': 2, 'l': 2, 'p': 1, 'a': 1, 'i': 1, 'n': 1, 'h': 1, 'e': 1})
Counter
实际上也是dict
的一个子类,上面的结果可以看出每个字符出现的次数。