collections --- Kiểu dữ liệu vùng chứa

Source code: Lib/collections/__init__.py


Mô-đun này triển khai các kiểu dữ liệu vùng chứa chuyên dụng cung cấp các lựa chọn thay thế cho các vùng chứa tích hợp cho mục đích chung của Python, dict, list, settuple.

namedtuple()

chức năng xuất xưởng để tạo các lớp con tuple với các trường được đặt tên

deque

vùng chứa giống như danh sách có khả năng bổ sung và bật lên nhanh chóng ở hai đầu

ChainMap

lớp giống như dict để tạo một chế độ xem duy nhất cho nhiều ánh xạ

Counter

lớp con dict để đếm các đối tượng hashable

OrderedDict

lớp con dict ghi nhớ các mục đặt hàng đã được thêm vào

defaultdict

lớp con dict gọi hàm xuất xưởng để cung cấp các giá trị còn thiếu

UserDict

bao bọc xung quanh các đối tượng từ điển để phân lớp dict dễ dàng hơn

UserList

trình bao bọc xung quanh các đối tượng danh sách để phân lớp danh sách dễ dàng hơn

UserString

trình bao bọc xung quanh các đối tượng chuỗi để phân lớp chuỗi dễ dàng hơn

đối tượng ChainMap

Added in version 3.3.

Lớp ChainMap được cung cấp để liên kết nhanh chóng một số ánh xạ để chúng có thể được coi là một đơn vị duy nhất. Nó thường nhanh hơn nhiều so với việc tạo một từ điển mới và chạy nhiều lệnh gọi update().

Lớp này có thể được sử dụng để mô phỏng các phạm vi lồng nhau và rất hữu ích trong việc tạo khuôn mẫu.

class collections.ChainMap(*maps)

Zz000zz nhóm nhiều ký tự hoặc ánh xạ khác lại với nhau để tạo một chế độ xem duy nhất, có thể cập nhật. Nếu không chỉ định maps thì một từ điển trống sẽ được cung cấp để chuỗi mới luôn có ít nhất một ánh xạ.

Các ánh xạ cơ bản được lưu trữ trong một danh sách. Danh sách đó là công khai và có thể được truy cập hoặc cập nhật bằng thuộc tính maps. Không có trạng thái nào khác.

Tra cứu tìm kiếm các ánh xạ cơ bản liên tục cho đến khi tìm thấy khóa. Ngược lại, việc ghi, cập nhật và xóa chỉ hoạt động trên ánh xạ đầu tiên.

Zz000zz kết hợp các ánh xạ cơ bản bằng cách tham chiếu. Vì vậy, nếu một trong các ánh xạ cơ bản được cập nhật, những thay đổi đó sẽ được phản ánh trong ChainMap.

Tất cả các phương pháp từ điển thông thường đều được hỗ trợ. Ngoài ra, còn có một thuộc tính maps, một phương thức tạo các bối cảnh con mới và một thuộc tính để truy cập tất cả trừ ánh xạ đầu tiên:

maps

Danh sách ánh xạ có thể cập nhật của người dùng. Danh sách được sắp xếp từ tìm kiếm đầu tiên đến tìm kiếm cuối cùng. Đây là trạng thái được lưu trữ duy nhất và có thể được sửa đổi để thay đổi ánh xạ nào được tìm kiếm. Danh sách phải luôn chứa ít nhất một ánh xạ.

new_child(m=None, **kwargs)

Trả về một ChainMap mới chứa bản đồ mới, theo sau là tất cả các bản đồ trong phiên bản hiện tại. Nếu m được chỉ định, nó sẽ trở thành bản đồ mới ở đầu danh sách ánh xạ; nếu không được chỉ định, một lệnh trống sẽ được sử dụng để lệnh gọi tới d.new_child() tương đương với: ChainMap({}, *d.maps). Nếu bất kỳ đối số từ khóa nào được chỉ định, chúng sẽ cập nhật bản đồ đã qua hoặc lệnh trống mới. Phương pháp này được sử dụng để tạo các bối cảnh con có thể được cập nhật mà không thay đổi giá trị trong bất kỳ ánh xạ gốc nào.

Thay đổi trong phiên bản 3.4: Tham số m tùy chọn đã được thêm vào.

Thay đổi trong phiên bản 3.10: Hỗ trợ đối số từ khóa đã được thêm vào.

parents

Thuộc tính trả về một ChainMap mới chứa tất cả các bản đồ trong phiên bản hiện tại ngoại trừ bản đồ đầu tiên. Điều này rất hữu ích để bỏ qua bản đồ đầu tiên trong tìm kiếm. Các trường hợp sử dụng tương tự như trường hợp sử dụng từ khóa nonlocal được sử dụng trong nested scopes. Các trường hợp sử dụng cũng song song với các trường hợp sử dụng chức năng super() tích hợp. Tham chiếu tới d.parents tương đương với: ChainMap(*d.maps[1:]).

Lưu ý, thứ tự lặp của ChainMap được xác định bằng cách quét các ánh xạ từ cuối đến đầu:

>>> đường  sở = {'âm nhạc': 'bach', 'nghệ thuật': 'rembrandt'}
>>> điều chỉnh = {'nghệ thuật': 'van gogh', 'opera': 'carmen'}
>>> list(ChainMap(điều chỉnh, đường  sở))
['âm nhạc', 'nghệ thuật', 'opera']

Điều này mang lại thứ tự tương tự như một loạt các lệnh gọi dict.update() bắt đầu bằng ánh xạ cuối cùng

>>> kết hợp = base.copy()
>>> kết hợp.update(điều chỉnh)
>>> danh sách (kết hợp)
['âm nhạc', 'nghệ thuật', 'opera']

Thay đổi trong phiên bản 3.9: Đã thêm hỗ trợ cho các toán tử ||=, được chỉ định trong PEP 584.

Xem thêm

  • Zz000zz trong Enthought CodeTools package có các tùy chọn để hỗ trợ ghi vào bất kỳ ánh xạ nào trong chuỗi.

  • Context class của Django để tạo khuôn mẫu là một chuỗi ánh xạ chỉ đọc. Nó cũng có tính năng đẩy và bật các ngữ cảnh tương tự như phương thức new_child() và thuộc tính parents.

  • Zz000zz có các tùy chọn để kiểm soát xem việc ghi và các đột biến khác chỉ áp dụng cho ánh xạ đầu tiên hay bất kỳ ánh xạ nào trong chuỗi.

  • Một greatly simplified read-only version of Chainmap.

ChainMap Ví dụ và Bí quyết

Phần này trình bày các cách tiếp cận khác nhau để làm việc với các bản đồ được xâu chuỗi.

Ví dụ về mô phỏng chuỗi tra cứu nội bộ của Python:

nhập nội dung
pylookup = ChainMap(locals(), Globals(), vars(buildins))

Ví dụ về việc cho phép các đối số dòng lệnh do người dùng chỉ định được ưu tiên hơn các biến môi trường, các biến môi trường này sẽ được ưu tiên hơn các giá trị mặc định

nhập hệ điều hành, argparse

mặc định = {'color': 'đỏ', 'người dùng': 'khách'}

trình phân tích  pháp = argparse.ArgumentParser()
parser.add_argument('-u', '--user')
parser.add_argument('-c', '--color')
không gian tên = trình phân tích  pháp.parse_args()
command_line_args = {k: v for k, v in vars(namespace).items() nếu v không phải  None}

kết hợp = ChainMap(command_line_args, os.environ, defaults)
in(kết hợp['color'])
in(kết hợp['người dùng'])

Các mẫu ví dụ về cách sử dụng lớp ChainMap để mô phỏng các ngữ cảnh lồng nhau:

c = Ngữ cảnh gốc ChainMap() # Create
d = c.new_child() # Create bối cảnh con lồng nhau
e = c.new_child() # Child của c, độc lập với d
e.maps[0] Từ điển ngữ cảnh # Current -- giống như từ điển địa phương của Python()
bối cảnh e.maps[-1] # Root -- giống như toàn cầu của Python()
Chuỗi ngữ cảnh e.parents # Enclosing -- giống như nonlocals của Python

d['x'] = 1 giá trị # Set trong ngữ cảnh hiện tại
d['x'] # Get khóa đầu tiên trong chuỗi ngữ cảnh
del d['x'] # Delete từ bối cảnh hiện tại
list(d) # All các giá trị lồng nhau
k in d # Check tất cả các giá trị lồng nhau
len(d) # Number của các giá trị lồng nhau
d.items() # All các mục lồng nhau
dict(d) # Flatten vào một từ điển thông thường

Lớp ChainMap chỉ thực hiện cập nhật (ghi và xóa) đối với ánh xạ đầu tiên trong chuỗi trong khi việc tra cứu sẽ tìm kiếm toàn bộ chuỗi. Tuy nhiên, nếu muốn ghi sâu và xóa, có thể dễ dàng tạo một lớp con cập nhật các khóa được tìm thấy sâu hơn trong chuỗi:

lớp DeepChainMap(ChainMap):
    'Biến thể của ChainMap cho phép cập nhật trực tiếp phạm vi bên trong'

    def __setitem__(tự, khóa, giá trị):
        để lập bản đồ trong self.maps:
            nếu khóa trong ánh xạ:
                ánh xạ [khóa] = giá trị
                trở về
        self.maps[0][key] = giá trị

    def __delitem__(tự, khóa):
        để lập bản đồ trong self.maps:
            nếu khóa trong ánh xạ:
                del ánh xạ [phím]
                trở về
        tăng KeyError(key)

>>> d = DeepChainMap({'ngựa vằn': 'đen'}, {'voi': 'xanh'}, {'sư tử': 'vàng'})
>>> d['lion'] = 'orange' # update một khóa hiện có giảm hai cấp
>>> d['snake'] = 'red' Các phím # new được thêm vào lệnh trên cùng
>>> del d['elephant'] # remove một khóa hiện có xuống một cấp
>>> kết quả d # display
DeepChainMap({'ngựa vằn': 'đen', 'rắn': 'đỏ'}, {}, {'sư tử': 'cam'})

đối tượng Counter

Một công cụ đếm được cung cấp để hỗ trợ việc kiểm đếm thuận tiện và nhanh chóng. Ví dụ:

>>> # Tally lần xuất hiện của các từ trong danh sách
>>> cnt = Bộ đếm()
>>> cho các từ trong ['red', 'blue', 'red', 'green', 'blue', 'blue']:
... cnt[từ] += 1
...
>>> cnt
Bộ đếm({'xanh': 3, 'đỏ': 2, 'xanh': 1})

>>> # Find mười từ thông dụng nhất trong Hamlet
>>> nhập lại
>>> từ = re.findall(r'\w+', open('hamlet.txt').read().low())
>>> Bộ đếm(từ).most_common(10)
[('the', 1143), ('và', 966), ('to', 762), ('of', 669), ('i', 631),
 ('bạn', 554), ('a', 546), ('của tôi', 514), ('thôn', 471), ('ở', 451)]
class collections.Counter(**kwargs)
class collections.Counter(iterable, /, **kwargs)
class collections.Counter(mapping, /, **kwargs)

Zz000zz là lớp con dict để đếm các đối tượng hashable. Nó là một bộ sưu tập trong đó các phần tử được lưu trữ dưới dạng khóa từ điển và số lượng của chúng được lưu dưới dạng giá trị từ điển. Số lượng được phép là bất kỳ giá trị số nguyên nào bao gồm số 0 hoặc số âm. Lớp Counter tương tự như túi hoặc nhiều bộ trong các ngôn ngữ khác.

Các phần tử được tính từ iterable hoặc được khởi tạo từ mapping (hoặc bộ đếm) khác:

>>> c = Counter()                           # a new, empty counter
>>> c = Counter('gallahad')                 # a new counter from an iterable
>>> c = Counter({'red': 4, 'blue': 2})      # a new counter from a mapping
>>> c = Counter(cats=4, dogs=8)             # a new counter from keyword args

Các đối tượng bộ đếm có giao diện từ điển ngoại trừ việc chúng trả về số 0 cho các mục bị thiếu thay vì tăng KeyError:

>>> c = Counter(['eggs', 'ham'])
>>> c['bacon']                              # count of a missing element is zero
0

Đặt số đếm về 0 sẽ không xóa phần tử khỏi bộ đếm. Sử dụng del để xóa hoàn toàn:

>>> c['sausage'] = 0                        # counter entry with a zero count
>>> del c['sausage']                        # del actually removes the entry

Added in version 3.1.

Thay đổi trong phiên bản 3.7: Là một lớp con dict, Counter kế thừa khả năng ghi nhớ thứ tự chèn. Các phép toán trên đối tượng Counter cũng giữ nguyên trật tự. Các kết quả được sắp xếp theo thời điểm một phần tử xuất hiện lần đầu trong toán hạng bên trái và sau đó theo thứ tự xuất hiện trong toán hạng bên phải.

Đối tượng truy cập hỗ trợ các phương thức bổ sung ngoài những phương thức có sẵn cho tất cả các từ điển:

elements()

Trả về một trình vòng lặp trên các phần tử lặp lại mỗi phần tử nhiều lần bằng số lượng của nó. Các phần tử được trả về theo thứ tự gặp lần đầu tiên. Nếu số lượng phần tử nhỏ hơn một, elements() sẽ bỏ qua phần tử đó.

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> sorted(c.elements())
['a', 'a', 'a', 'a', 'b', 'b']
most_common(n=None)

Trả về danh sách các phần tử phổ biến nhất của n và số lượng của chúng từ phổ biến nhất đến ít nhất. Nếu n bị bỏ qua hoặc None, most_common() trả về các phần tử all trong bộ đếm. Các phần tử có số lượng bằng nhau được sắp xếp theo thứ tự gặp lần đầu tiên:

>>> Counter('abracadabra').most_common(3)
[('a', 5), ('b', 2), ('r', 2)]
subtract(**kwargs)
subtract(iterable, /, **kwargs)
subtract(mapping, /, **kwargs)

Các phần tử được trừ khỏi iterable hoặc từ mapping (hoặc bộ đếm) khác. Giống như dict.update() nhưng trừ số lượng thay vì thay thế chúng. Cả đầu vào và đầu ra đều có thể bằng 0 hoặc âm.

>>> c = Counter(a=4, b=2, c=0, d=-2)
>>> d = Counter(a=1, b=2, c=3, d=4)
>>> c.subtract(d)
>>> c
Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})

Added in version 3.2.

total()

Tính tổng các số đếm.

>>> c = Counter(a=10, b=5, c=0)
>>> c.total()
15

Added in version 3.10.

Các phương thức từ điển thông thường có sẵn cho các đối tượng Counter ngoại trừ hai phương thức hoạt động khác nhau đối với các bộ đếm.

fromkeys(iterable)

Phương thức lớp này không được triển khai cho các đối tượng Counter.

update(**kwargs)
update(iterable, /, **kwargs)
update(mapping, /, **kwargs)

Các phần tử được tính từ iterable hoặc được bổ sung từ mapping (hoặc bộ đếm) khác. Giống như dict.update() nhưng thêm số lượng thay vì thay thế chúng. Ngoài ra, iterable được mong đợi là một chuỗi các phần tử chứ không phải là một chuỗi các cặp (key, value).

Bộ đếm hỗ trợ các toán tử so sánh phong phú cho các mối quan hệ đẳng thức, tập hợp con và tập hợp lớn: ==, !=, <, <=, >, >=. Tất cả các thử nghiệm đó đều coi các phần tử bị thiếu là có số lượng bằng 0 để Counter(a=1) == Counter(a=1, b=0) trả về giá trị đúng.

Thay đổi trong phiên bản 3.10: Hoạt động so sánh phong phú đã được thêm vào.

Thay đổi trong phiên bản 3.10: Trong kiểm tra tính bằng nhau, các phần tử bị thiếu được coi là có số lượng bằng 0. Trước đây, Counter(a=3)Counter(a=3, b=0) được coi là khác biệt.

Các mẫu phổ biến để làm việc với các đối tượng Counter:

c.total() # total trong tất cả các số đếm
c.clear() # reset tất cả đều được tính
list(c) # list các phần tử độc đáo
set(c) # convert thành một tập hợp
dict(c) # convert vào một từ điển thông thường
c.items() # access các cặp (elem, cnt)
Counter(dict(list_of_pairs)) # convert từ danh sách các cặp (elem, cnt)
c.most_common()[:-n-1:-1] # n các phần tử ít phổ biến nhất
+c # remove số 0 và số âm

Một số phép toán được cung cấp để kết hợp các đối tượng Counter để tạo ra nhiều bộ (bộ đếm có số lượng lớn hơn 0). Phép cộng và phép trừ kết hợp các bộ đếm bằng cách cộng hoặc trừ số lượng phần tử tương ứng. Giao lộ và hợp nhất trả về giá trị tối thiểu và tối đa của số đếm tương ứng. Bình đẳng và bao gồm so sánh số lượng tương ứng. Mỗi thao tác có thể chấp nhận đầu vào có số lượng đã ký, nhưng đầu ra sẽ loại trừ kết quả có số lượng bằng 0 hoặc ít hơn.

>>> c = Bộ đếm(a=3, b=1)
>>> d = Bộ đếm(a=1, b=2)
>>> c + d # add hai bộ đếm với nhau: c[x] + d[x]
Bộ đếm({'a': 4, 'b': 3})
>>> c - d # subtract (chỉ giữ số dương)
Bộ đếm({'a': 2})
>>> c & d # intersection: min(c[x], d[x])
Bộ đếm({'a': 1, 'b': 1})
>>> c | d # union: max(c[x], d[x])
Bộ đếm({'a': 3, 'b': 2})
>>> c == d # equality: c[x] == d[x]
sai
>>> c <= d # inclusion: c[x] <= d[x]
sai

Phép cộng và trừ một ngôi là các phím tắt để thêm một bộ đếm trống hoặc trừ một bộ đếm trống.

>>> c = Counter(a=2, b=-4)
>>> +c
Counter({'a': 2})
>>> -c
Counter({'b': 4})

Added in version 3.3: Đã thêm hỗ trợ cho các phép toán cộng, trừ đơn nhất và nhiều hoạt động tại chỗ.

Ghi chú

Bộ đếm được thiết kế chủ yếu để hoạt động với các số nguyên dương nhằm biểu thị số lần chạy; tuy nhiên, cần thận trọng để không loại trừ một cách không cần thiết các trường hợp sử dụng cần các loại hoặc giá trị âm khác. Để trợ giúp với những trường hợp sử dụng đó, phần này ghi lại các hạn chế về phạm vi và loại tối thiểu.

  • Bản thân lớp Counter là một lớp con từ điển không có hạn chế về khóa và giá trị của nó. Các giá trị dự định là các số đại diện cho số lượng, nhưng bạn could lưu trữ bất kỳ thứ gì trong trường giá trị.

  • Phương thức most_common() chỉ yêu cầu các giá trị có thể sắp xếp được.

  • Đối với các hoạt động tại chỗ như c[key] += 1, loại giá trị chỉ cần hỗ trợ phép cộng và phép trừ. Vì vậy, phân số, số float và số thập phân sẽ hoạt động và các giá trị âm được hỗ trợ. Điều tương tự cũng đúng với update()subtract() cho phép giá trị âm và 0 cho cả đầu vào và đầu ra.

  • Các phương pháp nhiều tập hợp chỉ được thiết kế cho các trường hợp sử dụng có giá trị dương. Đầu vào có thể âm hoặc bằng 0, nhưng chỉ những đầu ra có giá trị dương mới được tạo. Không có hạn chế về loại, nhưng loại giá trị cần hỗ trợ cộng, trừ và so sánh.

  • Phương thức elements() yêu cầu số nguyên. Nó bỏ qua số 0 và số âm.

Xem thêm

  • Bag class trong Smalltalk.

  • Mục nhập Wikipedia cho Multisets.

  • hướng dẫn C++ multisets với các ví dụ.

  • Để biết các phép toán trên nhiều tập hợp và trường hợp sử dụng của chúng, hãy xem Knuth, Donald. The Art of Computer Programming Volume II, Section 4.6.3, Exercise 19.

  • Để liệt kê tất cả các tập hợp nhiều phần riêng biệt có kích thước nhất định trên một tập hợp các phần tử nhất định, hãy xem itertools.combinations_with_replacement():

    map(Bộ đếm, tổ hợp_with_replacement('ABC', 2)) # --> AA AB AC BB BC CC
    

đối tượng deque

class collections.deque([iterable[, maxlen]])

Trả về một đối tượng deque mới được khởi tạo từ trái sang phải (sử dụng append()) với dữ liệu từ iterable. Nếu iterable không được chỉ định, deque mới sẽ trống.

Deques là sự khái quát hóa của ngăn xếp và hàng đợi (tên được phát âm là "bộ bài" và viết tắt của "hàng đợi hai đầu"). Deques hỗ trợ thêm và bật theo luồng an toàn, hiệu quả về bộ nhớ từ hai phía của deque với hiệu suất O(1) gần như giống nhau theo cả hai hướng.

Mặc dù các đối tượng list hỗ trợ các hoạt động tương tự, nhưng chúng được tối ưu hóa cho các hoạt động có độ dài cố định nhanh và phát sinh chi phí di chuyển bộ nhớ O(n) cho các hoạt động pop(0)insert(0, v) thay đổi cả kích thước và vị trí của biểu diễn dữ liệu cơ bản.

Nếu maxlen không được chỉ định hoặc là None, deques có thể tăng đến độ dài tùy ý. Nếu không, deque được giới hạn ở độ dài tối đa được chỉ định. Khi một deque có độ dài giới hạn đã đầy, khi các mục mới được thêm vào, một số mục tương ứng sẽ bị loại bỏ ở đầu đối diện. Deques có độ dài giới hạn cung cấp chức năng tương tự như bộ lọc tail trong Unix. Chúng cũng hữu ích để theo dõi các giao dịch và các nhóm dữ liệu khác mà chỉ quan tâm đến hoạt động gần đây nhất.

Các đối tượng Deque hỗ trợ các phương thức sau:

append(item, /)

Thêm item vào bên phải của deque.

appendleft(item, /)

Thêm item vào phía bên trái của deque.

clear()

Xóa tất cả các phần tử khỏi deque để lại độ dài 0.

copy()

Tạo một bản sao nông của deque.

Added in version 3.5.

count(value, /)

Đếm số phần tử deque bằng value.

Added in version 3.2.

extend(iterable, /)

Mở rộng phía bên phải của deque bằng cách nối thêm các phần tử từ đối số có thể lặp lại.

extendleft(iterable, /)

Mở rộng phía bên trái của deque bằng cách nối thêm các phần tử từ iterable. Lưu ý, chuỗi nối thêm bên trái dẫn đến việc đảo ngược thứ tự các phần tử trong đối số có thể lặp lại.

index(value[, start[, stop]])

Trả về vị trí của value trong deque (tại hoặc sau chỉ mục start và trước chỉ mục stop). Trả về kết quả khớp đầu tiên hoặc tăng ValueError nếu không tìm thấy.

Added in version 3.5.

insert(index, value, /)

Chèn value vào deque ở vị trí index.

Nếu việc chèn sẽ làm cho một deque giới hạn vượt quá maxlen, thì IndexError sẽ được nâng lên.

Added in version 3.5.

pop()

Xóa và trả về một phần tử ở phía bên phải của deque. Nếu không có phần tử nào, hãy tăng IndexError.

popleft()

Xóa và trả về một phần tử ở phía bên trái của deque. Nếu không có phần tử nào, hãy tăng IndexError.

remove(value, /)

Xóa lần xuất hiện đầu tiên của value. Nếu không tìm thấy, tăng ValueError.

reverse()

Đảo ngược các phần tử của deque tại chỗ rồi trả về None.

Added in version 3.2.

rotate(n=1, /)

Xoay các bước deque n sang phải. Nếu n âm, hãy xoay sang trái.

Khi deque không trống, xoay một bước sang phải tương đương với d.appendleft(d.pop()) và xoay một bước sang trái tương đương với d.append(d.popleft()).

Các đối tượng Deque cũng cung cấp một thuộc tính chỉ đọc:

maxlen

Kích thước tối đa của deque hoặc None nếu không bị giới hạn.

Added in version 3.1.

Ngoài những điều trên, deques còn hỗ trợ phép lặp, tẩy, len(d), reversed(d), copy.copy(d), copy.deepcopy(d), kiểm tra tư cách thành viên với toán tử in và tham chiếu chỉ số dưới như d[0] để truy cập phần tử đầu tiên. Quyền truy cập được lập chỉ mục là O(1) ở cả hai đầu nhưng chậm lại còn O(n) ở giữa. Để truy cập ngẫu nhiên nhanh, thay vào đó hãy sử dụng danh sách.

Bắt đầu từ phiên bản 3.5, deques hỗ trợ __add__(), __mul__()__imul__().

Ví dụ:

>>> từ deque nhập bộ sưu tập
>>> d = deque('ghi') # make một deque mới với ba mục
>>> cho phần tử trong d: # iterate trên các phần tử của deque
... print(elem.upper())
G
H
tôi

>>> d.append('j') # add một mục mới ở bên phải
>>> d.appendleft('f') # add một mục mới ở phía bên trái
>>> d # show đại diện của deque
deque(['f', 'g', 'h', 'i', 'j'])

>>> d.pop() # return và xóa mục ngoài cùng bên phải
'j'
>>> d.popleft() # return và xóa mục ngoài cùng bên trái
'f'
>>> list(d) # list nội dung của deque
['g', 'h', 'tôi']
>>> d[0] # peek ở mục ngoài cùng bên trái
'g'
>>> d[-1] # peek ở mục ngoài cùng bên phải
'tôi'

>>> list(reversed(d)) # list nội dung của deque đảo ngược
['tôi', 'h', 'g']
>>> 'h' trong d # search deque
đúng
>>> d.extend('jkl') # add nhiều phần tử cùng một lúc
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])
>>> d.rotate(1) # right xoay
>>> d
deque(['l', 'g', 'h', 'i', 'j', 'k'])
>>> xoay d.rotate(-1) # left
>>> d
deque(['g', 'h', 'i', 'j', 'k', 'l'])

>>> deque(reversed(d)) # make một deque mới theo thứ tự ngược lại
deque(['l', 'k', 'j', 'i', 'h', 'g'])
>>> d.clear() # empty deque
>>> d.pop() # cannot bật từ một deque trống
Traceback (cuộc gọi gần đây nhất):
    Tệp "<pyshell#6>", dòng 1, trong -toplevel-
        d.pop()
IndexError: bật từ một deque trống

>>> d.extendleft('abc') # extendleft() đảo ngược thứ tự đầu vào
>>> d
deque(['c', 'b', 'a'])

Công thức nấu ăn deque

Phần này trình bày các cách tiếp cận khác nhau để làm việc với deque.

Deques có độ dài giới hạn cung cấp chức năng tương tự như bộ lọc tail trong Unix

đuôi def(tên file, n=10):
    'Trả về n dòng cuối cùng của file'
    với open(filename)  f:
        trả về deque(f, n)

Một cách tiếp cận khác để sử dụng deques là duy trì một chuỗi các phần tử được thêm gần đây bằng cách thêm vào bên phải và bật lên bên trái

def moving_average(iterable, n=3):
    # moving_average([40, 30, 50, 46, 39, 44]) --> 40.0 42.0 45.0 43.0
    # zz000zz
    it = iter( thể lặp lại)
    d = deque(itertools.islice(it, n-1))
    d.appendleft(0)
    s = tổng(d)
    cho phần tử trong đó:
        s += elem - d.popleft()
        d.append(elem)
        năng suất s / n

Một round-robin scheduler có thể được triển khai bằng các trình vòng lặp đầu vào được lưu trữ trong deque. Các giá trị được tạo ra từ trình lặp hoạt động ở vị trí 0. Nếu trình vòng lặp đó đã hết, nó có thể bị xóa bằng popleft(); nếu không, nó có thể được quay trở lại điểm cuối bằng phương thức rotate()

def roundrobin(*iterables):
    "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
    iterators = deque(map(iter, iterables))
    trong khi vòng lặp:
        thử:
            trong khi Đúng:
                mang lại lợi nhuận tiếp theo(iterators[0])
                iterators.rotate(-1)
        ngoại trừ StopIteration:
            # Remove một trình lặp đã cạn kiệt.
            iterators.popleft()

Phương thức rotate() cung cấp một cách để thực hiện việc cắt và xóa deque. Ví dụ: việc triển khai del d[n] bằng Python thuần túy dựa vào phương thức rotate() để định vị các phần tử sẽ được bật lên

def xóa_nth(d, n):
    d.rotate(-n)
    d.popleft()
    d.rotate(n)

Để triển khai việc cắt deque, hãy sử dụng cách tiếp cận tương tự khi áp dụng rotate() để đưa phần tử đích về phía bên trái của deque. Xóa các mục cũ bằng popleft(), thêm các mục mới bằng extend(), sau đó đảo ngược vòng quay. Với những thay đổi nhỏ trong cách tiếp cận đó, thật dễ dàng thực hiện các thao tác ngăn xếp kiểu Forth như dup, drop, swap, over, pick, rotroll.

đối tượng defaultdict

class collections.defaultdict(default_factory=None, /, **kwargs)
class collections.defaultdict(default_factory, mapping, /, **kwargs)
class collections.defaultdict(default_factory, iterable, /, **kwargs)

Trả về một đối tượng giống như từ điển mới. defaultdict là một lớp con của lớp dict tích hợp sẵn. Nó ghi đè một phương thức và thêm một biến thể hiện có thể ghi. Chức năng còn lại tương tự như lớp dict và không được ghi lại ở đây.

Đối số đầu tiên cung cấp giá trị ban đầu cho thuộc tính default_factory; nó mặc định là None. Tất cả các đối số còn lại được xử lý giống như khi chúng được chuyển đến hàm tạo dict, bao gồm cả các đối số từ khóa.

Các đối tượng defaultdict hỗ trợ phương thức sau ngoài các hoạt động dict tiêu chuẩn:

__missing__(key, /)

Nếu thuộc tính default_factoryNone, điều này sẽ tạo ra một ngoại lệ KeyError với key làm đối số.

Nếu default_factory không phải là None, thì nó được gọi mà không có đối số để cung cấp giá trị mặc định cho key đã cho, giá trị này sẽ được chèn vào từ điển cho key và được trả về.

Nếu việc gọi default_factory gây ra một ngoại lệ thì ngoại lệ này sẽ được truyền đi không thay đổi.

Phương thức này được gọi bằng phương thức __getitem__() của lớp dict khi không tìm thấy khóa được yêu cầu; bất cứ thứ gì nó trả về hoặc tăng lên sẽ được __getitem__() trả lại hoặc tăng lên.

Lưu ý rằng __missing__() được gọi là not cho bất kỳ hoạt động nào ngoài __getitem__(). Điều này có nghĩa là get() sẽ, giống như các từ điển thông thường, trả về None làm mặc định thay vì sử dụng default_factory.

Các đối tượng defaultdict hỗ trợ biến thể hiện sau:

default_factory

Thuộc tính này được sử dụng bởi phương thức __missing__(); nó được khởi tạo từ đối số đầu tiên cho hàm tạo, nếu có hoặc tới None, nếu không có.

Thay đổi trong phiên bản 3.9: Đã thêm các toán tử hợp nhất (|) và cập nhật (|=), được chỉ định trong PEP 584.

defaultdict Ví dụ

Sử dụng list làm default_factory, thật dễ dàng để nhóm một chuỗi các cặp khóa-giá trị vào một từ điển danh sách:

>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

Khi gặp mỗi khóa lần đầu tiên, nó chưa có trong ánh xạ; do đó, một mục nhập được tạo tự động bằng hàm default_factory và trả về một list trống. Sau đó, thao tác list.append() sẽ gắn giá trị vào danh sách mới. Khi gặp lại các phím, quá trình tra cứu sẽ diễn ra bình thường (trả về danh sách cho khóa đó) và thao tác list.append() sẽ thêm một giá trị khác vào danh sách. Kỹ thuật này đơn giản và nhanh hơn kỹ thuật tương đương sử dụng dict.setdefault():

>>> d = {}
>>> for k, v in s:
...     d.setdefault(k, []).append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]

Đặt default_factory thành int làm cho defaultdict trở nên hữu ích cho việc đếm (như túi hoặc nhiều bộ trong các ngôn ngữ khác):

>>> s = 'mississippi'
>>> d = defaultdict(int)
>>> for k in s:
...     d[k] += 1
...
>>> sorted(d.items())
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]

Khi gặp một chữ cái lần đầu tiên, nó bị thiếu trong ánh xạ, vì vậy hàm default_factory gọi int() để cung cấp số đếm mặc định bằng 0. Sau đó, thao tác tăng dần sẽ tính tổng số cho mỗi chữ cái.

Hàm int() luôn trả về 0 chỉ là trường hợp đặc biệt của hàm hằng. Một cách nhanh hơn và linh hoạt hơn để tạo các hàm hằng là sử dụng hàm lambda có thể cung cấp bất kỳ giá trị không đổi nào (không chỉ bằng 0):

>>> def constant_factory(value):
...     return lambda: value
...
>>> d = defaultdict(constant_factory('<missing>'))
>>> d.update(name='John', action='ran')
>>> '%(name)s %(action)s to %(object)s' % d
'John ran to <missing>'

Việc đặt default_factory thành set sẽ làm cho defaultdict trở nên hữu ích trong việc xây dựng từ điển các bộ:

>>> s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
>>> d = defaultdict(set)
>>> for k, v in s:
...     d[k].add(v)
...
>>> sorted(d.items())
[('blue', {2, 4}), ('red', {1, 3})]

namedtuple() Chức năng xuất xưởng dành cho bộ dữ liệu có trường được đặt tên

Các bộ dữ liệu được đặt tên gán ý nghĩa cho từng vị trí trong một bộ dữ liệu và cho phép mã tự ghi lại dễ đọc hơn. Chúng có thể được sử dụng ở bất cứ nơi nào sử dụng bộ dữ liệu thông thường và chúng thêm khả năng truy cập các trường theo tên thay vì chỉ mục vị trí.

collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

Trả về một lớp con bộ dữ liệu mới có tên typename. Lớp con mới được sử dụng để tạo các đối tượng giống như bộ dữ liệu có các trường có thể truy cập được bằng cách tra cứu thuộc tính cũng như có thể lập chỉ mục và lặp lại được. Các phiên bản của lớp con cũng có một chuỗi tài liệu hữu ích (với typenamefield_names) và một phương thức __repr__() hữu ích liệt kê nội dung bộ dữ liệu ở định dạng name=value.

Zz003zz là một chuỗi các chuỗi như ['x', 'y']. Ngoài ra, field_names có thể là một chuỗi đơn với mỗi tên trường được phân tách bằng khoảng trắng và/hoặc dấu phẩy, ví dụ: 'x y' hoặc 'x, y'.

Bất kỳ mã định danh Python hợp lệ nào cũng có thể được sử dụng cho tên trường ngoại trừ các tên bắt đầu bằng dấu gạch dưới. Giá trị nhận dạng hợp lệ bao gồm các chữ cái, chữ số và dấu gạch dưới nhưng không bắt đầu bằng chữ số hoặc dấu gạch dưới và không thể là keyword như class, for, return, global, pass hoặc raise.

Nếu rename đúng, tên trường không hợp lệ sẽ tự động được thay thế bằng tên vị trí. Ví dụ: ['abc', 'def', 'ghi', 'abc'] được chuyển đổi thành ['abc', '_1', 'ghi', '_3'], loại bỏ từ khóa def và tên trường trùng lặp abc.

defaults có thể là None hoặc iterable có giá trị mặc định. Vì các trường có giá trị mặc định phải đứng sau bất kỳ trường nào không có giá trị mặc định nên defaults được áp dụng cho các tham số ngoài cùng bên phải. Ví dụ: nếu tên trường là ['x', 'y', 'z'] và giá trị mặc định là (1, 2) thì x sẽ là đối số bắt buộc, y sẽ mặc định là 1z sẽ mặc định là 2.

Nếu module được xác định, thuộc tính __module__ của bộ dữ liệu được đặt tên sẽ được đặt thành giá trị đó.

Các phiên bản bộ dữ liệu được đặt tên không có từ điển cho từng phiên bản, vì vậy chúng nhẹ và không yêu cầu nhiều bộ nhớ hơn các bộ dữ liệu thông thường.

Để hỗ trợ việc tẩy, lớp tuple được đặt tên phải được gán cho một biến khớp với typename.

Thay đổi trong phiên bản 3.1: Đã thêm hỗ trợ cho rename.

Thay đổi trong phiên bản 3.6: Các thông số verboserename trở thành keyword-only arguments.

Thay đổi trong phiên bản 3.6: Đã thêm tham số module.

Thay đổi trong phiên bản 3.7: Đã xóa tham số verbose và thuộc tính _source.

Thay đổi trong phiên bản 3.7: Đã thêm tham số defaults và thuộc tính _field_defaults.

>>>  dụ # Basic
>>> Điểm = nametuple('Điểm', ['x', 'y'])
>>> p = Điểm(11, y=22) # instantiate với các đối số vị trí hoặc từ khóa
>>> p[0] + p[1] # indexable giống như bộ dữ liệu đơn giản (11, 22)
33
>>> x, y = p # unpack giống như một bộ dữ liệu thông thường
>>> x, y
(11, 22)
>>> p.x + p.y # fields cũng có thể truy cập theo tên
33
>>> p # readable __repr__ với kiểu tên=value
Điểm(x=11, y=22)

Các bộ dữ liệu được đặt tên đặc biệt hữu ích trong việc gán tên trường cho các bộ dữ liệu kết quả được trả về bởi các mô-đun csv hoặc sqlite3:

Nhân viênRecord = têntuple('EmployeeRecord', 'tên, tuổi, chức danh, bộ phận, mức lương')

nhập csv
cho emp trong bản đồ(EmployeeRecord._make, csv.reader(open("employees.csv", "rb"))):
    print(emp.name, emp.title)

nhập sqlite3
conn = sqlite3.connect('/companydata')
con trỏ = conn.cursor()
con trỏ.execute('tên, tuổi, chức danh, bộ phận, cấp lương của nhân viên FROM')
cho emp trong bản đồ(EmployeeRecord._make,cursor.fetchall()):
    print(emp.name, emp.title)

Ngoài các phương thức được kế thừa từ các bộ dữ liệu, các bộ dữ liệu được đặt tên còn hỗ trợ ba phương thức bổ sung và hai thuộc tính. Để tránh xung đột với tên trường, tên phương thức và thuộc tính bắt đầu bằng dấu gạch dưới.

classmethod somenamedtuple._make(iterable, /)

Phương thức lớp tạo một phiên bản mới từ một chuỗi hiện có hoặc có thể lặp lại.

>>> t = [11, 22]
>>> Điểm._make(t)
Điểm(x=11, y=22)
somenamedtuple._asdict()

Trả về một dict mới ánh xạ tên trường tới các giá trị tương ứng của chúng:

>>> p = Điểm(x=11, y=22)
>>> p._asdict()
{'x': 11, 'y': 22}

Thay đổi trong phiên bản 3.1: Trả về OrderedDict thay vì dict thông thường.

Thay đổi trong phiên bản 3.8: Trả về dict thông thường thay vì OrderedDict. Kể từ Python 3.7, các lệnh thông thường được đảm bảo có thứ tự. Nếu cần có các tính năng bổ sung của OrderedDict, cách khắc phục được đề xuất là chuyển kết quả sang loại mong muốn: OrderedDict(nt._asdict()).

somenamedtuple._replace(**kwargs)

Trả về một phiên bản mới của bộ dữ liệu được đặt tên thay thế các trường được chỉ định bằng các giá trị mới

>>> p = Điểm(x=11, y=22)
>>> p._replace(x=33)
Điểm(x=33, y=22)

>>> đối với partnum, ghi vào Inventory.items():
... Inventory[partnum] = record._replace(price=newprice[partnum], timestamp=time.now())

Các bộ dữ liệu được đặt tên cũng được hỗ trợ bởi hàm chung copy.replace().

Thay đổi trong phiên bản 3.13: Tăng TypeError thay vì ValueError đối với các đối số từ khóa không hợp lệ.

somenamedtuple._fields

Bộ chuỗi liệt kê tên trường. Hữu ích cho việc xem xét nội tâm và tạo các kiểu bộ dữ liệu được đặt tên mới từ các bộ dữ liệu có tên hiện có.

>>> p._fields # view tên trường
('x', 'y')

>>> Color = nametuple('Color', 'red green blue')
>>> Pixel = nametuple('Pixel', Point._fields + Color._fields)
>>> Điểm ảnh(11, 22, 128, 255, 0)
Pixel(x=11, y=22, đỏ=128, xanh lục=255, xanh dương=0)
somenamedtuple._field_defaults

Từ điển ánh xạ tên trường thành giá trị mặc định.

>>> Tài khoản = nametuple('Tài khoản', ['loại', 'số dư'], defaults=[0])
>>> Tài khoản._field_defaults
{'cân bằng': 0}
>>> Tài khoản('cao cấp')
Tài khoản(loại='cao cấp', số dư=0)

Để truy xuất trường có tên được lưu dưới dạng chuỗi, hãy sử dụng hàm getattr():

>>> getattr(p, 'x')
11

Để chuyển đổi một từ điển thành một bộ có tên, hãy sử dụng toán tử sao đôi (như được mô tả trong Giải nén danh sách đối số):

>>> d = {'x': 11, 'y': 22}
>>> Point(**d)
Point(x=11, y=22)

Vì bộ dữ liệu được đặt tên là một lớp Python thông thường nên rất dễ dàng thêm hoặc thay đổi chức năng bằng một lớp con. Dưới đây là cách thêm trường được tính toán và định dạng in có chiều rộng cố định:

>>> Điểm lớp(namedtuple('Điểm', ['x', 'y'])):
... __khe__ = ()
... @property
... def hypot(self):
... trả lại (self.x ** 2 + self.y ** 2) ** 0,5
... def __str__(tự):
... return 'Điểm: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)

>>> cho p trong Điểm(3, 4), Điểm(14, 5/7):
... in(p)
Điểm: x= 3.000 y= 4.000 hypot= 5.000
Điểm: x=14.000 y= 0,714 hypot=14,018

Lớp con hiển thị ở trên đặt __slots__ thành một bộ trống. Điều này giúp duy trì yêu cầu bộ nhớ ở mức thấp bằng cách ngăn chặn việc tạo từ điển phiên bản.

Phân lớp không hữu ích cho việc thêm các trường mới được lưu trữ. Thay vào đó, chỉ cần tạo một loại bộ dữ liệu có tên mới từ thuộc tính _fields:

>>> Point3D = namedtuple('Point3D', Point._fields + ('z',))

Chuỗi tài liệu có thể được tùy chỉnh bằng cách thực hiện các phép gán trực tiếp cho các trường __doc__:

>>> Book = namedtuple('Book', ['id', 'title', 'authors'])
>>> Book.__doc__ += ': Hardcover book in active collection'
>>> Book.id.__doc__ = '13-digit ISBN'
>>> Book.title.__doc__ = 'Title of first printing'
>>> Book.authors.__doc__ = 'List of authors sorted by last name'

Thay đổi trong phiên bản 3.5: Chuỗi tài liệu thuộc tính có thể ghi được.

Xem thêm

  • Xem typing.NamedTuple để biết cách thêm gợi ý loại cho các bộ dữ liệu được đặt tên. Nó cũng cung cấp một ký hiệu trang nhã bằng cách sử dụng từ khóa class:

    Thành phần lớp (NamedTuple):
        phần_số: int
        trọng lượng: phao
         tả: Tùy chọn[str] = Không 
    
  • Xem types.SimpleNamespace() để biết không gian tên có thể thay đổi dựa trên từ điển cơ bản thay vì bộ dữ liệu.

  • Mô-đun dataclasses cung cấp trình trang trí và các chức năng để tự động thêm các phương thức đặc biệt được tạo vào các lớp do người dùng xác định.

đối tượng OrderedDict

Từ điển được sắp xếp cũng giống như các từ điển thông thường nhưng có thêm một số tính năng liên quan đến hoạt động sắp xếp. Giờ đây, chúng trở nên ít quan trọng hơn khi lớp dict tích hợp sẵn có khả năng ghi nhớ thứ tự chèn (hành vi mới này đã được đảm bảo trong Python 3.7).

Một số điểm khác biệt so với dict vẫn còn:

  • Zz000zz thông thường được thiết kế để thực hiện các hoạt động lập bản đồ rất tốt. Thứ tự chèn theo dõi chỉ là thứ yếu.

  • Zz000zz được thiết kế để thực hiện tốt các hoạt động sắp xếp lại. Hiệu quả về không gian, tốc độ lặp và hiệu suất của các hoạt động cập nhật chỉ là thứ yếu.

  • Thuật toán OrderedDict có thể xử lý các thao tác sắp xếp lại thường xuyên tốt hơn dict. Như được trình bày trong các công thức bên dưới, điều này làm cho nó phù hợp để triển khai các loại bộ nhớ đệm LRU khác nhau.

  • Hoạt động bình đẳng cho OrderedDict kiểm tra thứ tự khớp.

    Một dict thông thường có thể mô phỏng bài kiểm tra đẳng thức nhạy cảm với thứ tự với p == q and all(k1 == k2 for k1, k2 in zip(p, q)).

  • Phương thức popitem() của OrderedDict có chữ ký khác. Nó chấp nhận một đối số tùy chọn để chỉ định mục nào được bật lên.

    Một dict thông thường có thể mô phỏng od.popitem(last=True) của OrderedDict với d.popitem() được đảm bảo sẽ bật mục ngoài cùng bên phải (cuối cùng).

    Một dict thông thường có thể mô phỏng od.popitem(last=False) của OrderedDict với (k := next(iter(d)), d.pop(k)), nó sẽ trả về và xóa mục ngoài cùng bên trái (đầu tiên) nếu nó tồn tại.

  • OrderedDict có phương pháp move_to_end() để định vị lại một phần tử đến điểm cuối một cách hiệu quả.

    Một dict thông thường có thể mô phỏng od.move_to_end(k, last=True) của OrderedDict với d[k] = d.pop(k), thao tác này sẽ di chuyển khóa và giá trị liên quan của nó đến vị trí ngoài cùng bên phải (cuối cùng).

    Một dict thông thường không có sự tương đương hiệu quả với od.move_to_end(k, last=False) của OrderedDict, nó di chuyển khóa và giá trị liên quan của nó sang vị trí ngoài cùng bên trái (đầu tiên).

  • Cho đến Python 3.8, dict thiếu phương thức __reversed__().

class collections.OrderedDict(**kwargs)
class collections.OrderedDict(mapping, /, **kwargs)
class collections.OrderedDict(iterable, /, **kwargs)

Trả về một phiên bản của lớp con dict có các phương thức chuyên biệt để sắp xếp lại thứ tự từ điển.

Added in version 3.1.

popitem(last=True)

Phương thức popitem() cho từ điển có thứ tự trả về và xóa một cặp (khóa, giá trị). Các cặp được trả về theo thứ tự LIFO nếu last đúng hoặc thứ tự FIFO nếu sai.

move_to_end(key, last=True)

Di chuyển key hiện có sang một trong hai đầu của từ điển được sắp xếp. Mục này được chuyển sang đầu bên phải nếu last là đúng (mặc định) hoặc về đầu nếu last là sai. Tăng KeyError nếu key không tồn tại:

>>> d = OrderedDict.fromkeys('abcde')
>>> d.move_to_end('b')
>>> ''.join(d)
'acdeb'
>>> d.move_to_end('b', Last=False)
>>> ''.join(d)
'bacde'

Added in version 3.2.

Ngoài các phương pháp ánh xạ thông thường, từ điển có thứ tự còn hỗ trợ phép lặp ngược bằng reversed().

Kiểm tra sự bình đẳng giữa các đối tượng OrderedDict có độ nhạy thứ tự cao và gần tương đương với list(od1.items())==list(od2.items()).

Kiểm tra sự bình đẳng giữa các đối tượng OrderedDict và các đối tượng Mapping khác không phân biệt thứ tự như từ điển thông thường. Điều này cho phép các đối tượng OrderedDict được thay thế ở bất cứ nơi nào sử dụng từ điển thông thường.

Thay đổi trong phiên bản 3.5: Các mục, khóa và giá trị views của OrderedDict hiện hỗ trợ lặp lại ngược bằng reversed().

Thay đổi trong phiên bản 3.6: Với sự chấp nhận của PEP 468, thứ tự được giữ lại cho các đối số từ khóa được truyền cho hàm tạo OrderedDict và phương thức update() của nó.

Thay đổi trong phiên bản 3.9: Đã thêm các toán tử hợp nhất (|) và cập nhật (|=), được chỉ định trong PEP 584.

OrderedDict Ví dụ và Bí quyết

Thật đơn giản để tạo một biến thể từ điển có thứ tự để ghi nhớ thứ tự các khóa được chèn last. Nếu một mục nhập mới ghi đè lên một mục nhập hiện có, vị trí chèn ban đầu sẽ được thay đổi và chuyển về cuối:

lớp LastUpdatedOrderedDict(OrderedDict):
    'Lưu trữ các mục theo thứ tự các khóa được thêm lần cuối'

    def __setitem__(tự, khóa, giá trị):
        super().__setitem__(khóa, giá trị)
        self.move_to_end(key)

Một OrderedDict cũng sẽ hữu ích khi triển khai các biến thể của functools.lru_cache():

từ bộ sưu tập nhập OrderedDict
tính từ thời điểm nhập khẩu

lớp TimeBoundedLRU:
    "LRU Cache vô hiệu hóa và làm mới các mục cũ."

    def __init__(self, func, maxsize=128, maxage=30):
        self.cache = OrderedDict() # { args : (dấu thời gian, kết quả)}
        self.func = func
        self.maxsize = kích thước tối đa
        self.maxage = tối đa

    def __call__(self, *args):
        nếu lập luận trong self.cache:
            self.cache.move_to_end(args)
            dấu thời gian, kết quả = self.cache[args]
            if time() - dấu thời gian <= self.maxage:
                kết quả trả về
        kết quả = self.func(*args)
        self.cache[args] = time(), kết quả
        nếu len(self.cache) > self.maxsize:
            self.cache.popitem(last=False)
        kết quả trả về
lớp MultiHitLRUCache:
    """ Bộ nhớ đệm LRU trì hoãn việc lưu kết quả vào bộ nhớ đệm cho đến khi
        nó đã được yêu cầu nhiều lần.

        Để tránh xóa bộ đệm LRU bằng các yêu cầu một lần,
        chúng tôi không lưu vào bộ nhớ đệm cho đến khi yêu cầu được thực hiện nhiều lần.

    """

    def __init__(self, func, maxsize=128, maxrequests=4096, cache_after=1):
        self.requests = OrderedDict() # { uncached_key : request_count }
        self.cache = OrderedDict() # { cached_key : function_result }
        self.func = func
        self.maxrequests = maxrequests # max số lượng yêu cầu không được lưu vào bộ nhớ đệm
        self.maxsize = maxsize # max số giá trị trả về được lưu trữ
        self.cache_after = cache_after

    def __call__(self, *args):
        nếu lập luận trong self.cache:
            self.cache.move_to_end(args)
            trả về self.cache[args]
        kết quả = self.func(*args)
        self.requests[args] = self.requests.get(args, 0) + 1
        if self.requests[args] <= self.cache_after:
            self.requests.move_to_end(args)
            if len(self.requests) > self.maxrequests:
                self.requests.popitem(last=False)
        khác:
            self.requests.pop(args, None)
            self.cache[args] = kết quả
            nếu len(self.cache) > self.maxsize:
                self.cache.popitem(last=False)
        kết quả trả về

đối tượng UserDict

Lớp UserDict hoạt động như một lớp bao quanh các đối tượng từ điển. Nhu cầu về lớp này đã được thay thế một phần bằng khả năng phân lớp trực tiếp từ dict; tuy nhiên, lớp này có thể dễ dàng làm việc hơn vì từ điển cơ bản có thể truy cập được dưới dạng một thuộc tính.

class collections.UserDict(**kwargs)
class collections.UserDict(mapping, /, **kwargs)
class collections.UserDict(iterable, /, **kwargs)

Lớp mô phỏng một từ điển. Nội dung của phiên bản được lưu giữ trong một từ điển thông thường, có thể truy cập được thông qua thuộc tính data của phiên bản UserDict. Nếu các đối số được cung cấp, chúng sẽ được dùng để khởi tạo data, giống như một từ điển thông thường.

Ngoài việc hỗ trợ các phương thức và thao tác ánh xạ, các phiên bản UserDict còn cung cấp thuộc tính sau:

data

Một từ điển thực sự được sử dụng để lưu trữ nội dung của lớp UserDict.

đối tượng UserList

Lớp này hoạt động như một trình bao bọc xung quanh các đối tượng danh sách. Đây là lớp cơ sở hữu ích cho các lớp giống như danh sách của riêng bạn, lớp này có thể kế thừa từ chúng và ghi đè các phương thức hiện có hoặc thêm các phương thức mới. Bằng cách này, người ta có thể thêm các hành vi mới vào danh sách.

Nhu cầu về lớp này đã được thay thế một phần bằng khả năng phân lớp trực tiếp từ list; tuy nhiên, lớp này có thể dễ dàng làm việc hơn vì danh sách cơ bản có thể truy cập được dưới dạng một thuộc tính.

class collections.UserList([list])

Lớp mô phỏng một danh sách. Nội dung của phiên bản được lưu giữ trong một danh sách thông thường, có thể truy cập được thông qua thuộc tính data của phiên bản UserList. Nội dung của phiên bản ban đầu được đặt thành bản sao của list, mặc định là danh sách trống []. list có thể là bất kỳ lần lặp nào, ví dụ như danh sách Python thực hoặc đối tượng UserList.

Ngoài việc hỗ trợ các phương thức và thao tác của các chuỗi có thể thay đổi, các phiên bản UserList còn cung cấp thuộc tính sau:

data

Một đối tượng list thực sự được sử dụng để lưu trữ nội dung của lớp UserList.

Subclassing requirements: Các lớp con của UserList dự kiến ​​​​sẽ cung cấp một hàm tạo có thể được gọi mà không có đối số hoặc một đối số. Liệt kê các thao tác trả về một chuỗi mới cố gắng tạo một phiên bản của lớp triển khai thực tế. Để làm như vậy, nó giả định rằng hàm tạo có thể được gọi với một tham số duy nhất, đó là một đối tượng chuỗi được sử dụng làm nguồn dữ liệu.

Nếu một lớp dẫn xuất không muốn tuân thủ yêu cầu này thì tất cả các phương thức đặc biệt được lớp này hỗ trợ sẽ cần phải được ghi đè; vui lòng tham khảo các nguồn để biết thông tin về các phương pháp cần được cung cấp trong trường hợp đó.

đối tượng UserString

Lớp UserString hoạt động như một lớp bao quanh các đối tượng chuỗi. Nhu cầu về lớp này đã được thay thế một phần bằng khả năng phân lớp trực tiếp từ str; tuy nhiên, lớp này có thể dễ dàng làm việc hơn vì chuỗi cơ bản có thể truy cập được dưới dạng một thuộc tính.

class collections.UserString(seq)

Lớp mô phỏng một đối tượng chuỗi. Nội dung của phiên bản được lưu giữ trong một đối tượng chuỗi thông thường, có thể truy cập được thông qua thuộc tính data của phiên bản UserString. Nội dung của phiên bản ban đầu được đặt thành bản sao của seq. Đối số seq có thể là bất kỳ đối tượng nào có thể được chuyển đổi thành chuỗi bằng hàm str() tích hợp.

Ngoài việc hỗ trợ các phương thức và thao tác của chuỗi, các phiên bản UserString còn cung cấp thuộc tính sau:

data

Một đối tượng str thực sự được sử dụng để lưu trữ nội dung của lớp UserString.

Thay đổi trong phiên bản 3.5: Các phương pháp mới __getnewargs__, __rmod__, casefold, format_map, isprintablemaketrans.