Python 内置模块 Collections

Python 的内置模块 Collections,包括 namedtuple,deque,Counter,OrderedDict

#namedtuple()

factory function for creating tuple subclasses with named fields

 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
# -*- coding:utf-8 -*-
# 练习使用namedtuple

from math import sqrt
from collections import namedtuple

# namedtuple的三种声明方式
Circle = namedtuple('Circle', ['x', 'y', 'r']) 
# Circle = namedtuple('Circle', 'x y r')
# Circle = namedtuple('Circle', 'x, y, r')


def judge(c1, c2):
    dis_of_circle_center = sqrt((c1.x - c2.x) ** 2 + (c1.y - c2.y) ** 2)
    if dis_of_circle_center == 0 and c1.r == c2.r:
        print('两圆重合,既是内切也是内含也是相交')
    elif dis_of_circle_center < abs(c1.r - c2[2]):  # c2.r和c2[2]是效果相同的两种索引方式
        print('内含')
    elif dis_of_circle_center == abs(c1.r - c2.r):
        print('两圆内切')
    elif abs(c1.r - c2.r) < dis_of_circle_center < c1.r + c2.r:
        print('两圆相交')
    elif dis_of_circle_center == c1.r+c2.r:
        print('两圆外切')
    else:
        print('外离')


if __name__ == '__main__':
    x1 = float(input('请输入圆1的圆心坐标x:'))
    y1 = float(input('请输入圆1的圆心坐标y:'))
    r1 = float(input('请输入圆1的半径r:'))

    x2 = float(input('请输入圆2的圆心坐标x:'))
    y2 = float(input('请输入圆2的圆心坐标y:'))
    r2 = float(input('请输入圆2的半径r:'))

    circle1 = Circle(x1, y1, r1)
    circle2 = Circle(x2, y2, r2)

    print(circle1, circle2)  # Circle(x=1.0, y=2.0, r=3.0) Circle(x=4.0, y=5.0, r=6.0)

    judge(circle1, circle2)

#deque

list-like container with fast appends and pops on either end.

It is short for “double-ended queue”. Deques support thread-safe, memory efficient appends and pops from either side of the deque with approximately the same O(1) performance in either direction. Though list objects support similar operations, they are optimized for fast fixed-length operations and incur O(n) memory movement costs for pop(0) and insert(0, v) operations which change both the size and position of the underlying data representation.

 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
# -*- coding:utf-8 -*-
# deque操作

from collections import deque

d1 = deque([1, 2, 3, [4, 5]])

# append(x) Add x to the right side of the deque.
d1.append(6)
print(d1)  # deque([1, 2, 3, [4, 5], 6])

# appendleft(x) Add x to the left side of the deque.
d1.appendleft(0)
print(d1)  # deque([0, 1, 2, 3, [4, 5], 6])

# copy() 浅拷贝
d2 = d1.copy()
print(d2)  # deque([0, 1, 2, 3, [4, 5], 6])
d1.pop()
print(d1, d2)  # deque([0, 1, 2, 3, [4, 5]]) deque([0, 1, 2, 3, [4, 5], 6])
d1.popleft()
print(d1, d2)  # deque([1, 2, 3, [4, 5]]) deque([0, 1, 2, 3, [4, 5], 6])
d1.append(7)
print(d1, d2)  # deque([1, 2, 3, [4, 5], 7]) deque([0, 1, 2, 3, [4, 5], 6])
# 改变原list中引用的子list的值时,d2中的对应值也会变化
d1[3][0] = 8
print(d1, d2)  # deque([1, 2, 3, [8, 5], 7]) deque([0, 1, 2, 3, [8, 5], 6])
# extend(iterable) Extend the right side of the deque by appending elements from the iterable argument.
d1.extend([9, 10])
print(d1, d2)  # deque([1, 2, 3, [8, 5], 7, 9, 10]) deque([0, 1, 2, 3, [8, 5], 6])

# extendleft(iterable) Extend the left side of the deque by appending elements from iterable.
# Note, the series of left appends results in reversing the order of elements in the iterable argument.
d1.extendleft([0, -1, -2, -3])
print(d1)  # deque([-3, -2, -1, 0, 1, 2, 3, [8, 5], 7, 9, 10])

# count(x) Count the number of deque elements equal to x.
print(d1.count(5))  # 0
print(d1.count(0))  # 1

# index(x) Returns the position of x firstly match in the deque
print(d1.index(5))  # ValueError: 5 is not in deque
print(d1.index(0))  # 3

# remove(value) Remove the first occurrence of value.
d1.append(0)
d1.remove(0)
print(d1)  # deque([-3, -2, -1, 1, 2, 3, [8, 5], 7, 9, 10, 0])
print(d1.remove(5))  # ValueError: deque.remove(x): x not in deque

# reverse() Reverse the elements of the deque in-place and then return None.
d1.reverse()
print(d1)  # deque([0, 10, 9, 7, [8, 5], 3, 2, 1, -1, -2, -3])

# clear()
print(d1.clear())  # None


d3 = deque([0, 1, 2, 3, 4], maxlen=4)
print(d3)  # deque([1, 2, 3, 4], maxlen=4)

# insert(i, x) Insert x into the deque at position i.
# If the insertion would cause a bounded deque to grow beyond maxlen, an IndexError is raised.
d3.pop()
d3.insert(1, 5)
print(d3)  # deque([1, 5, 2, 3], maxlen=4)
print(d3.insert(5, 2))  # IndexError: deque already at its maximum size

# rotate(n=1) Rotate the deque n steps to the right(顺时针). If n is negative, rotate to the left(逆时针).
# When the deque is not empty, rotating one step to the right is equivalent to d.appendleft(d.pop())
# and rotating one step to the left is equivalent to d.append(d.popleft()).
d3.rotate(3)
print(d3)  # deque([5, 2, 3, 1], maxlen=4)
d3.rotate(-2)
print(d3)  # deque([3, 1, 5, 2], maxlen=4)

d4 = d3.copy()
d3[2] = 4
print(d3, d4)  # deque([3, 1, 4, 2], maxlen=4) deque([3, 1, 5, 2], maxlen=4)

#Counter

dict subclass for counting hashable objects.

A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts. The Counter class is similar to bags or multisets in other languages.

#初始化方法

1
2
3
4
c1 = Counter()  # a new, empty counter
c2 = Counter('gallahad')  # a new counter from an iterable
c3 = Counter({'red': 4, 'blue': 2})  # a new counter from a mapping
c4 = Counter(cats=4, dogs=8, birds=14)  # a new counter from keyword args

#常用方法

  • elements() requires integer counts. It ignores zero and negative counts. Return an iterator over elements repeating each as many times as its count. Elements are returned in arbitrary(随意的) order.

  • most_common([n]) Return a list of the n most common elements and their counts from the most common to the least. Elements with equal counts are ordered arbitrarily.

  • subtract([iterable-or-mapping])

    1
    2
    3
    4
    5
    6
    7
    8
    
    c5 = Counter({'a': 1, 'b': 2, 'c': 3, 'd': 4})
    c6 = Counter({'a': -4, 'b': 2, 'c': 1, 'e': 4})
    c5.subtract(c6)
    print(c5)  # Counter({'a': 5, 'd': 4, 'c': 2, 'b': 0, 'e': -4})
    # 在c5中e的计数为0,把Counter中的一个元素的值设为0并没有把这个元素从Counter中移除,要真正的移除使用del c['a']
    
    # print(c5 - c6)  # Counter({'a': 5, 'd': 4, 'c': 2})
    # 直接使用减号是将c5中与c6中键值都相同的元素删除,键相同值不同的元素值相减
    
  • update()

    1
    2
    3
    4
    5
    
    c5 = Counter({'a': 1, 'b': 2, 'c': 3, 'd': 4})
    c6 = Counter({'a': -4, 'b': 2, 'c': 1, 'e': 4})
    
    c5.update(c6)
    print(c5)  # Counter({'b': 4, 'c': 4, 'd': 4, 'e': 4, 'a': -3})
    
  • Others

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    
    >>> c = Counter(a=3, b=1)
    >>> d = Counter(a=1, b=2)
    >>> c + d                       # add two counters together:  c[x] + d[x]
    Counter({'a': 4, 'b': 3})
    >>> c - d                       # subtract (keeping only positive counts)
    Counter({'a': 2})
    >>> c & d                       # intersection:  min(c[x], d[x]) # doctest: +SKIP
    Counter({'a': 1, 'b': 1})
    >>> c | d                       # union:  max(c[x], d[x])
    Counter({'a': 3, 'b': 2})
    

#OrderedDict

dict subclass that remembers the order entries were added.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
>>> # regular unsorted dictionary
>>> d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}

>>> # dictionary sorted by key
>>> OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

>>> # dictionary sorted by value
>>> OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

>>> # dictionary sorted by length of the key string
>>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0])))
OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)])
  • popitem(last=True)

    The popitem() method for ordered dictionaries returns and removes a (key, value) pair. The pairs are returned in LIFO order if last is true or FIFO order if false.

  • move_to_end(key, last=True)

    Move an existing key to either end of an ordered dictionary. The item is moved to the right end if last is true (the default) or to the beginning if last is false. Raises KeyError if the key does not exist.

    1
    2
    3
    4
    5
    6
    7
    
    >>> d = OrderedDict.fromkeys('abcde')
    >>> d.move_to_end('b')
    >>> ''.join(d.keys())
    'acdeb'
    >>> d.move_to_end('b', last=False)
    >>> ''.join(d.keys())
    'bacde'
    

#References

python.org

updatedupdated2022-05-082022-05-08