случайный вызов.randint() с -1?

#python #python-3.x #random

#python #python-3.x #Случайный

Вопрос:

Может кто-нибудь объяснить, почему в range конце in random.randint(0, len(messages) - 1) имеет минус 1? Список содержит 9 значений:

 import random

messages = ['It is certain',
            'It is decidedly so',
            'Yes definitely',
            'Reply hazy try again',
            'Ask again later',
            'Concentrate and ask again',
            'My reply is no',
            'Outlook not so good',
            'Very doubtful']

select_number = random.randint(0, len(messages) - 1)
list_select  = messages[select_number]
print(list_select)
  

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

1. Было бы полезно, если бы вы уточнили, почему именно это кажется вам странным.

2. Потому что это было написано кем-то, кто не очень хорошо знаком с Python? Может быть, они сделали прямой перевод кода с другого языка. Разумным способом было бы использовать random.choice или оставаться ближе к оригиналу, select_number = random.randrange(len(messages))

3. По иронии судьбы, randint это было позднее дополнение к random , для людей, которые нашли randrange запутанным. Но если у кого-то есть проблемы с randrange тем, как они справляются с range , или срезают нотацию?

Ответ №1:

random.randint() второе значение является включительным. Он выберет число из 10 случайных целых чисел ( 0 , 1 , 2 3 , 4 5 , 6 7 , 8 9 ,,,,,,,,,,,,,,,,,,,,,,, ,, и,,,), где у вас есть только 9 индексов в списке. len(messages) есть 9 , но нет messages[9] индекса, так как индексация Python начинается с 0 . Вместо этого единственные допустимые индексы идут от 0 до 8 .

Таким образом, при использовании random.randint(0, len(messages) - 1) функция ограничивается выбором допустимого индекса для messages списка.

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

 list_select = random.choice(messages)
  

В других ситуациях random.randrange() тоже может быть вариант, поскольку он не включает конечную точку в возможные значения, работая аналогично индексации Python, нарезке и range() :

 index_select = random.randrange(len(messages))
  

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

1. Не будет ли выбор индекса случайным образом через random.randint и выбор этого элемента, по сравнению с использованием random.choice для выбора элемента из списка, одним и тем же?

2. @DeveshKumarSingh: да, конечный результат тот же. Но random.choice() позволяет вам легче избегать ошибок и становится чище и понятнее при чтении кода.

3. Имеет смысл, я предполагаю, что внутренняя логика random.choice может быть использована random.randint в некотором роде!

4. @DeveshKumarSingh: Нет, он использует внутренний _rand_below метод, см. Исходный код .

Ответ №2:

Это потому, что random.randint случайным образом выбирает индексы списка от 0 до 8 и выбирает сообщение.
Теперь индексы списка переходят от 0 к len(messages)-1=8 .
Согласно документам: https://docs.python.org/3/library/random.html#random.randint

random.randint(a, b) . Возвращает случайное целое число N такое, что a <= N <= b. Псевдоним для randrange(a, b 1).

Что означает, что выбрано целое число от 0 до 8, которые являются допустимыми индексами списка, если бы мы вместо этого поставили len(messages) , индекс 9 тоже был бы выбран, что является недопустимым индексом для списка в Python, поскольку списки Python являются 0-indexed

Ответ №3:

random.randint(a, b) Возвращает случайное целое число N такое, что a <= N <= b .

len(messages) - 1 Это немного сложно, потому что диапазон вашего списка действительно равен 9, но вы должны помнить, что подсчет начинается с 0 вместо 1. Итак, в вашем случае len(messages) будет возвращено 9, но первый элемент находится в messages[0]

Это означает, что в вашем случае select_number = random.randint(0, len(messages) - 1) будет выдано число от 0 до len(messages) - 1 9 — 1.