Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Python

Counter (Bộ đếm) trong Python


Một Counter là một container (chứa) theo dõi xem bao nhiêu lần các giá trị tương đương được thêm vào. Lớp Counter của Python là một phần của module collections và là subclass của dictionary.

Python Counter

Chúng ta có thể coi counter như một tập hợp không có thứ tự của các mục, nơi các mục được lưu trữ làm khóa dictionary và số lượng của chúng làm giá trị dictionary.

Số lượng mục của Counter có thể là số nguyên dương, zero hoặc âm. Tuy không có giới hạn về khóa và giá trị nhưng nói chung giá trị dự định là số nhưng chúng ta cũng có thể lưu trữ các kiểu đối tượng khác.

Khởi tạo (Initializing)

Counter hỗ trợ ba dạng khởi tạo. Constructor của nó có thể được gọi với một chuỗi các mục, một dictionary chứa khóa và số lượng, hoặc sử dụng keyword arguments ánh xạ tên chuỗi sang số lượng.

import collections
print(collections.Counter(['a', 'b', 'c', 'a', 'b', 'b']))
print(collections.Counter({'a': 2, 'b': 3, 'c': 1}))
print(collections.Counter(a=2, b=3, c=1))

Kết quả từ cả ba dạng khởi tạo đều giống nhau:

Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})
Counter({'b': 3, 'a': 2, 'c': 1})

Để tạo counter rỗng, truyền counter không có đối số và điền dữ liệu qua phương thức update.

import collections
c = collections.Counter()
print('Khởi tạo: ', c)
c.update('abcddcba')
print('Chuỗi: ', c)
c.update({'a': 1, 'd': 5})
print('Dict: ', c)

Kết quả

Khởi tạo: Counter()
Chuỗi: Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2})
Dict: Counter({'d': 7, 'a': 3, 'b': 2, 'c': 2})

Truy xuất Số lượng (Accessing Counts)

Khi counter đã được điền dữ liệu, các giá trị của nó có thể được lấy qua API dictionary.

import collections
c = collections.Counter('abcddcba')
for letter in 'abcdef':
    print('%s : %d' % (letter, c[letter]))

Kết quả

a : 2
b : 2
c : 2
d : 2
e : 0
f : 0

Counter không ném KeyError cho các mục không biết (như mục e & f trong chương trình trên). Nếu một giá trị chưa xuất hiện trong đầu vào, số lượng của nó là 0 (như mục không biết e & f trong kết quả trên).

Phương thức elements() trả về iterator tạo ra tất cả các mục biết đến bởi Counter.

import collections
c = collections.Counter('Python Counters')
c['z'] = 0
print(c)
print(list(c.elements()))

Kết quả

Counter({'t': 2, 'o': 2, 'n': 2, 'P': 1, 'y': 1, 'h': 1, ' ': 1, 'C': 1, 'u': 1, 'e': 1, 'r': 1, 's': 1, 'z': 0})
['P', 'y', 't', 't', 'h', 'o', 'o', 'n', 'n', ' ', 'C', 'u', 'e', 'r', 's']

Thứ tự các phần tử không cố định, và các mục với số lượng nhỏ hơn 0 không được bao gồm.

Để tạo ra các đầu vào phổ biến nhất từ n đầu vào và số lượng tương ứng, chúng ta dùng hàm most_common().

import collections
c = collections.Counter()
texts = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'''
for word in texts:
    c.update(word.rstrip().lower())
print("Năm chữ cái phổ biến nhất trong văn bản: ")
for letter, count in c.most_common(5):
    print("%s: %7d" % (letter, count))

Kết quả

Năm chữ cái phổ biến nhất trong văn bản:
i:      42
e:      38
t:      32
o:      29
u:      29

Ví dụ trên đếm các chữ cái xuất hiện trong văn bản (hoặc bạn có thể coi như một tệp) để tạo phân phối tần suất, sau đó in năm chữ cái phổ biến nhất. Bỏ qua đối số của most_common() tạo ra danh sách tất cả các mục, theo thứ tự tần suất.

Phép toán (Arithmetic)

Các instance Counter hỗ trợ phép toán và phép toán tập hợp cho việc tổng hợp kết quả.

import collections
c1 = collections.Counter(['a', 'b', 'c', 'a', 'b', 'b'])
c2 = collections.Counter('alphabet')
print('C1: ', c1)
print('C2: ', c2)
print('\nKết hợp số lượng: ')
print(c1 + c2)
print('\nTrừ: ')
print(c1 - c2)
print('\nGiao (lấy minimums dương): ')
print(c1 & c2)
print('\nHợp (lấy maximums): ')
print(c1 | c2)

Kết quả

C1: Counter({'b': 3, 'a': 2, 'c': 1})
C2: Counter({'a': 2, 'l': 1, 'p': 1, 'h': 1, 'b': 1, 'e': 1, 't': 1})

Kết hợp số lượng:
Counter({'a': 4, 'b': 4, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

Trừ:
Counter({'b': 2, 'c': 1})

Giao (lấy minimums dương):
Counter({'a': 2, 'b': 1})

Hợp (lấy maximums):
Counter({'b': 3, 'a': 2, 'c': 1, 'l': 1, 'p': 1, 'h': 1, 'e': 1, 't': 1})

Mỗi khi một counter mới được tạo qua một phép toán, bất kỳ mục nào với số lượng zero hoặc âm sẽ bị loại bỏ.