эквивалент random.choice() по порядку

#python #list #function #random #iteration

#python #Список #функция #Случайный #итерация

Вопрос:

Я знаю, что с помощью циклов for элементы в списке отображаются по порядку, но они отображаются только сразу.

например:

 >>> list = [1,2,3,4,5]
>>> for i in list:
...     print(i)
...
1
2
3
4
5
  

То же самое, если я делаю это с диапазоном и длиной, в отношении индексов.

Но что делает random.choice(), так это берет случайный элемент в списке и затем печатает его при каждом вызове функции.

например:

 >>> from random import choice
>>> list = [1,2,3,4,5]
>>> print(choice(list))
1
>>> print(choice(list))
5
>>> print(choice(list))
4
  

Существует ли эквивалент random.choice(), но для печати элементов в списках по порядку каждый раз, когда это требуется?

Нравится:

 >>> list = [1,2,3,4,5]
>>> print(function(list))
1
>>> print(function(list))
2
>>> print(function(list))
3
  

И так далее, пока не будет напечатан последний элемент в списке, чтобы список снова вернулся к первому индексу при следующей печати.

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

1. Неявное глобальное состояние, задействованное в предлагаемом вами API, является кошмаром для удобства использования и огромным источником ошибок. Просто следите за индексом самостоятельно или используйте явный итератор.

2. Я действительно не понимаю, в каком смысле это эквивалентно случайному выбору.

3. Эквивалентно по результату.

4. Однако это совсем не эквивалентно результату.

5. И так далее. — и так далее, как? Что произойдет при 6-м вызове print(function(list)) ,? Вы бы тоже хотели предоставить функцию перезапуска?

Ответ №1:

Вы можете использовать iter для создания итератора для значений в списке. Затем используйте next для доступа к следующему элементу.

 values = [1, 2, 4, 8]
data = iter(values)
print(next(data))
print(next(data))
  

Вы получите StopIteration сообщение об ошибке при попытке вызова next после того, как у вас уже есть последний элемент.

Поскольку iter создается итератор, вы не можете вернуться в последовательность. Если вы хотите начать все сначала, вам придется создать новый итератор с data = iter(values) помощью .

Если вы хотите повторить данные после того, как вы достигли последнего значения, которое вы можете использовать itertools.cyle .

 from itertools import cycle
values = [1, 2, 4, 8]
data = iter(cycle((values))
print(next(data))
print(next(data))  # repeat this as often as you like
  

Предостережение: не пытайтесь создать список из этого итератора, потому что он неограничен.

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

1. Я полагаю, что, если реализовано в функции, вы можете использовать if, чтобы вернуться к началу. Спасибо.

2. Чтобы вернуться к началу, просто data = iter(values) повторите.

3. @idkman Нет, если реализовано в функции, вы не можете использовать if, чтобы вернуться к началу. iter Объект используется при его использовании либо путем явной итерации, либо с помощью next функции. Возможно, Матиас мог бы прояснить этот аспект в своем ответе.

4. Оооо, интересно! Спасибо за разъяснения и ответы!

Ответ №2:

Вы могли бы создать свой собственный.
Цикл while будет повторять итерацию чисел столько, сколько вам нужно.
Yield x говорит ‘возвращает это значение, но при повторном вызове я начну с того места, на котором остановился.

Редактировать: нужно перехватывать пустые списки.

 def loop(lst):
    if lst:
        while True:
            for x in lst:
                yield x
  

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

1. from itertools import cycle

2. Спасибо за совет! Я попробую это.

3. cycle имеет более сложное предложение на 1,5 шага с созданием списка для себя и помещением пустой проверки в while : docs.python.org/3/library/itertools.html#itertools.cycle

4. О, я понимаю. Спасибо, что сказали об этом.