Hướng dẫn python heapq nlargest key - khóa lớn nhất của python heapq

Mã nguồn: lib/heapq.py Lib/heapq.py

Mô -đun này cung cấp việc triển khai thuật toán hàng đợi Heap, còn được gọi là thuật toán hàng đợi ưu tiên.

Thoát nước là những cây nhị phân mà mọi nút cha mẹ đều có giá trị nhỏ hơn hoặc bằng với bất kỳ con nào của nó. Việc triển khai này sử dụng các mảng mà heap[k] > h = [] >>> heappush[h, [5, 'write code']] >>> heappush[h, [7, 'release product']] >>> heappush[h, [1, 'write spec']] >>> heappush[h, [3, 'create tests']] >>> heappop[h] [1, 'write spec'] 0 hoặc bạn có thể chuyển đổi danh sách dân cư thành một đống thông qua chức năng

>>> h = []
>>> heappush[h, [5, 'write code']]
>>> heappush[h, [7, 'release product']]
>>> heappush[h, [1, 'write spec']]
>>> heappush[h, [3, 'create tests']]
>>> heappop[h]
[1, 'write spec']
1.

Các chức năng sau được cung cấp:

________ 12 ________ 13 [heap, mặt hàng] ¶[heap, item]

Đẩy mặt hàng giá trị lên đống, duy trì heap bất biến.

________ 12 ________ 15 [Heap] ¶[heap]

Pop và trả lại vật phẩm nhỏ nhất từ ​​đống, duy trì bất biến. Nếu đống trống,

>>> h = []
>>> heappush[h, [5, 'write code']]
>>> heappush[h, [7, 'release product']]
>>> heappush[h, [1, 'write spec']]
>>> heappush[h, [3, 'create tests']]
>>> heappop[h]
[1, 'write spec']
6 sẽ được nâng lên. Để truy cập mục nhỏ nhất mà không cần bật nó, hãy sử dụng heap[0].

________ 12 ________ 19 [heap, mặt hàng] ¶[heap, item]

Đẩy vật phẩm lên đống, sau đó bật và trả lại vật phẩm nhỏ nhất từ ​​đống. Hành động kết hợp chạy hiệu quả hơn

from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]
0, sau đó là một cuộc gọi riêng đến
from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]
1.

________ 12 ________ 23 [x][x]

Biến đổi danh sách X thành một đống, tại chỗ, trong thời gian tuyến tính.

________ 12 ________ 25 [heap, mặt hàng] ¶[heap, item]

Pop và trả lại các mặt hàng nhỏ nhất từ ​​đống, và cũng đẩy mục mới. Kích thước đống không thay đổi. Nếu đống trống,

>>> h = []
>>> heappush[h, [5, 'write code']]
>>> heappush[h, [7, 'release product']]
>>> heappush[h, [1, 'write spec']]
>>> heappush[h, [3, 'create tests']]
>>> heappop[h]
[1, 'write spec']
6 sẽ được nâng lên.

Hoạt động một bước này hiệu quả hơn so với

from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]
1 theo sau là
from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]
0 và có thể phù hợp hơn khi sử dụng một đống kích thước cố định. Sự kết hợp pop/push luôn trả về một phần tử từ đống và thay thế nó bằng vật phẩm.

Giá trị được trả về có thể lớn hơn mục được thêm vào. Nếu đó không phải là mong muốn, hãy xem xét sử dụng

from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]
9 thay thế. Sự kết hợp đẩy/pop của nó trả về các giá trị nhỏ hơn của hai giá trị, để lại giá trị lớn hơn trên đống.

Mô -đun cũng cung cấp ba chức năng mục đích chung dựa trên đống.

________ 12 ________ 31 [*iterables, key = none, lùi = sai] ¶[*iterables, key=None, reverse=False]

Hợp nhất nhiều đầu vào được sắp xếp vào một đầu ra được sắp xếp duy nhất [ví dụ: hợp nhất các mục nhập thời gian từ nhiều tệp nhật ký]. Trả về một trình lặp qua các giá trị được sắp xếp.iterator over the sorted values.

Tương tự như

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
2 nhưng trả về một điều khác, không kéo dữ liệu vào bộ nhớ cùng một lúc và giả sử rằng mỗi luồng đầu vào đã được sắp xếp [nhỏ nhất đến lớn nhất].

Có hai đối số tùy chọn phải được chỉ định là đối số từ khóa.

Khóa chỉ định chức năng chính của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử đầu vào. Giá trị mặc định là

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
3 [so sánh trực tiếp các phần tử].key function of one argument that is used to extract a comparison key from each input element. The default value is
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
3 [compare the elements directly].

Đảo ngược là một giá trị boolean. Nếu được đặt thành

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
4, thì các phần tử đầu vào được hợp nhất như thể mỗi so sánh được đảo ngược. Để đạt được hành vi tương tự như
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
5, tất cả các vòng lặp phải được sắp xếp từ lớn nhất đến nhỏ nhất.

Đã thay đổi trong phiên bản 3.5: Đã thêm các tham số khóa và đảo ngược tùy chọn.Added the optional key and reverse parameters.

________ 12 ________ 37 [n, có thể lặp lại, khóa = không] ¶[n, iterable, key=None]

Trả về một danh sách với các phần tử lớn nhất từ ​​bộ dữ liệu được xác định bởi ITable. Khóa, nếu được cung cấp, chỉ định hàm của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong ITable [ví dụ:

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
8]. Tương đương với:
pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
9.

________ 12 ________ 41 [n, có thể lặp lại, khóa = không] ¶[n, iterable, key=None]

Trả về một danh sách với n phần tử nhỏ nhất từ ​​bộ dữ liệu được xác định bởi ITable. Khóa, nếu được cung cấp, chỉ định hàm của một đối số được sử dụng để trích xuất một khóa so sánh từ mỗi phần tử trong ITable [ví dụ:

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']
8]. Tương đương với:
                               0

              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
3.

Hai hàm sau hoạt động tốt nhất cho các giá trị nhỏ hơn của n. Đối với các giá trị lớn hơn, việc sử dụng hàm

                               0

              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
4 hiệu quả hơn. Ngoài ra, khi
                               0

              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
5, việc sử dụng các hàm
                               0

              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
6 và
                               0

              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
7 tích hợp sẽ hiệu quả hơn. Nếu việc sử dụng lặp đi lặp lại của các chức năng này là bắt buộc, hãy xem xét việc biến số thứ có thể lặp lại thành một đống thực tế.

Ví dụ cơ bản

Một Heapsort có thể được thực hiện bằng cách đẩy tất cả các giá trị lên một đống và sau đó bật ra các giá trị nhỏ nhất cùng một lúc:

>>> def heapsort[iterable]:
...     h = []
...     for value in iterable:
...         heappush[h, value]
...     return [heappop[h] for i in range[len[h]]]
...
>>> heapsort[[1, 3, 5, 7, 9, 2, 4, 6, 8, 0]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Điều này tương tự như

                               0

              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
8, nhưng không giống như
                               0

              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
4, việc triển khai này không ổn định.

Các yếu tố đống có thể là bộ dữ liệu. Điều này rất hữu ích để gán các giá trị so sánh [như ưu tiên nhiệm vụ] cùng với bản ghi chính được theo dõi:

>>> h = []
>>> heappush[h, [5, 'write code']]
>>> heappush[h, [7, 'release product']]
>>> heappush[h, [1, 'write spec']]
>>> heappush[h, [3, 'create tests']]
>>> heappop[h]
[1, 'write spec']

Ghi chú triển khai hàng đợi ưu tiên

Hàng đợi ưu tiên là sử dụng phổ biến cho một đống và nó đưa ra một số thách thức thực hiện:

  • Sắp xếp sự ổn định: Làm thế nào để bạn nhận được hai nhiệm vụ với các ưu tiên bằng nhau được trả lại theo thứ tự ban đầu chúng được thêm vào?

  • So sánh Tuple phá vỡ các cặp [ưu tiên, nhiệm vụ] nếu các ưu tiên bằng nhau và các tác vụ không có thứ tự so sánh mặc định.

  • Nếu mức độ ưu tiên của một tác vụ thay đổi, làm thế nào để bạn di chuyển nó đến một vị trí mới trong đống?

  • Hoặc nếu một nhiệm vụ đang chờ xử lý cần phải bị xóa, làm thế nào để bạn tìm thấy nó và loại bỏ nó khỏi hàng đợi?

Một giải pháp cho hai thử thách đầu tiên là lưu trữ các mục dưới dạng danh sách 3 phần tử bao gồm ưu tiên, số lượng nhập cảnh và nhiệm vụ. Số lượng mục nhập đóng vai trò là một công cụ phá vỡ để hai nhiệm vụ có cùng mức độ ưu tiên được trả về theo thứ tự chúng được thêm vào. Và vì không có hai số nhập nào là giống nhau, so sánh tuple sẽ không bao giờ cố gắng so sánh trực tiếp hai nhiệm vụ.

Một giải pháp khác cho vấn đề của các tác vụ không thể so sánh là tạo ra một lớp trình bao bọc bỏ qua mục nhiệm vụ và chỉ so sánh trường ưu tiên:

from dataclasses import dataclass, field
from typing import Any

@dataclass[order=True]
class PrioritizedItem:
    priority: int
    item: Any=field[compare=False]

Các thách thức còn lại xoay quanh việc tìm kiếm một nhiệm vụ đang chờ xử lý và thực hiện các thay đổi đối với mức độ ưu tiên của nó hoặc loại bỏ nó hoàn toàn. Tìm một nhiệm vụ có thể được thực hiện với một từ điển chỉ vào một mục trong hàng đợi.

Việc loại bỏ mục nhập hoặc thay đổi mức độ ưu tiên của nó khó khăn hơn vì nó sẽ phá vỡ cấu trúc đống bất biến. Vì vậy, một giải pháp khả thi là đánh dấu mục nhập được xóa và thêm một mục mới với mức độ ưu tiên sửa đổi:

pq = []                         # list of entries arranged in a heap
entry_finder = {}               # mapping of tasks to entries
REMOVED = ''      # placeholder for a removed task
counter = itertools.count[]     # unique sequence count

def add_task[task, priority=0]:
    'Add a new task or update the priority of an existing task'
    if task in entry_finder:
        remove_task[task]
    count = next[counter]
    entry = [priority, count, task]
    entry_finder[task] = entry
    heappush[pq, entry]

def remove_task[task]:
    'Mark an existing task as REMOVED.  Raise KeyError if not found.'
    entry = entry_finder.pop[task]
    entry[-1] = REMOVED

def pop_task[]:
    'Remove and return the lowest priority task. Raise KeyError if empty.'
    while pq:
        priority, count, task = heappop[pq]
        if task is not REMOVED:
            del entry_finder[task]
            return task
    raise KeyError['pop from an empty priority queue']

Học thuyết¶

Các đống là các mảng mà heap[k]

Bài Viết Liên Quan

Chủ Đề