Python个人笔记-3

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串起来并组成一个逻辑上的dictChainMap本身也是一个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的一个子类,上面的结果可以看出每个字符出现的次数。

参考:ChainMap廖雪峰

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值