Найдите следующий доступный номер в списке python

#python

#python

Вопрос:

У меня есть список целых чисел, которые представляют, сколько раз использовался элемент, и мне нужно найти следующий номер в последовательности, который использовался наименьшее количество раз (его может даже не быть в списке)

Количество элементов является динамическим, в примере используется 9, но это может быть. Кроме того, количество раз, когда он может появляться, также является динамическим.

We have X items, all of which are allowed to be used y times

Пример.

У нас есть 9 элементов, оба из которых разрешено использовать 2 раза, но их следует использовать по порядку.

 [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2]
  

приведенное выше должно возвращать 3 в качестве следующего доступного элемента

 [1, 2, 3, 4, 5]
  

приведенное выше должно возвращать 6 в качестве следующего доступного элемента

 [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  

приведенное выше ничего не должно возвращать, поскольку больше нет доступных

У меня уже есть функция, которая проверяет, отображается ли число при максимальном количестве использований

 def is_item_available(item_number: int, uses: int, used_items: List):
    """Check if the item is available.
    Args:
        item_number (int): item number to be checked
        uses (int): number of uses allowed
        used_items (list): list of items currently used in a session
    Returns:
        bool: returns True if used item count is less than the uses number
    """
    return used_items.count(item_number) < uses
  

Комментарии:

1. Пожалуйста, обновите свой вопрос кодом, который вы пробовали.

2. Вы можете определить функцию генератора, которая будет выдавать каждый раз следующий индекс или создавать итератор из itertools.cycle() и использовать next() . l = iter(cycle([1, 2, 3, 4, 5, 6, 7, 8, 9])) ; next(l)

3. Можете ли вы предоставить некоторую информацию об элементах? Это заданный список целых чисел? Все ли они являются регулярными? Всегда ли они находятся в диапазоне (от 0 до чего-то)?

4. Может быть, я что-то пропустил, но почему бы не начать с наименьшего возможного до максимально возможного и посчитать, если отображается меньше допустимого, если да, верните его и готово, если нет, перейдите к следующему. Если все они отображаются как минимум максимально допустимый возврат ничего?

Ответ №1:

Я думаю, что эта функция работает, если числа гарантированно будут от 1 до 9:

 def next_item(used_items):
    if (used_items[-1] == 9 and len(used_items) == 18):
        return "nothing"
    elif (used_items[-1] == 9):
        return 1
    else:
        return used_items[-1]   1

  

Комментарии:

1. Как насчет таких случаев, как list = [1]*17 [2] ? Ожидаемый ответ — 2, но вы бы вернули nothing

2. Кроме того, что такое used_items.length ?

3. @SerialLazer да, эта функция работает только в том случае, если числа от 1 до 9 и каждый раз увеличиваются на 1.

4. Я думаю, что это жесткое ограничение на вопрос, основанное на примерах OP!

5. Даже в этом случае это неправильно, потому что OP запрашивает the least used item . Как насчет list=[1-9]*3 ? Ожидается, что он ничего не вернет, но вы вернете 1!

Ответ №2:

Наиболее оптимальным решением было бы использовать минимальную кучу для хранения оперативных данных и извлечения верхней части кучи:

 import collections, heapq

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2]

## Counter will maintain the count of each element in the list
counter = collections.Counter(lst)

## We now create a min-heap with (counter.count, list.val) as elements
heap = [(value, key) for key,value in dict(counter).items()]

## Now fetch the top element from the min-heap. By definition, this would correspond to the minimum list.val with minimum count

smallest_element = heapq.nsmallest(1, heap)

## If the list.val is already been used twice, return "None" else return the list.val 
if smallest_element[0] > 1:
  return None
return smallest_element[1]
  

Комментарии:

1. не так ли return smallest_element[0][1] ? поскольку [1] будет вне индекса.

2. @NeilHickman smallest_element — это просто кортеж, извлеченный из минимальной кучи

3. и вы не можете сравнить кортеж с int?

4. Разве это не должно быть heap = [(value, key) for key,value in dict(counter).items()]; heapq.heapify(heap) ?

5. Если я правильно понимаю ваш алгоритм, он возвращает наименьшее значение, если оно доступно, и None если наименьшее значение недоступно. Но что, если доступно второе по величине значение? None В этом случае вы не должны возвращаться. В любом случае, я настоятельно рекомендую добавить пояснения относительно того, как должен работать этот алгоритм.