Почему список необходим для random.choice

Это, вероятно, очень прямой вопрос, но хотелось бы просто объяснить, почему?

В приведенном ниже коде требуется список, чтобы получить случайную карту.

import random card = random.choice (["hearts", "clubs", "frogs"]) 

Я озадачен тем, почему для этого нужен список и почему я не могу этого сделать.

 import = random card = random.choice("hearts" , "clubs", "frogs") 

Я в порядке, я не могу этого сделать, я просто хотел бы знать, почему?

7 Solutions collect form web for “Почему список необходим для random.choice”

потому что, первый фрагмент

 ["hearts","clubs","frogs"] 

отправляет только один аргумент функции (список)

а второй отправляет три строки в функцию. Выбор функции оборудован только одним аргументом. Таким образом, вы должны отправить его в виде списка или всего, что может быть проиндексировано, так что он выбирает случайный индекс для возврата значения

Из-за закона Мерфи: все, что может быть сделано неверным путем, будет сделано некорректным путем кем-то, когда-нибудь. Предлагаемый API потребует

 random.choice(*lst) 

когда значения, которые нужно выбрать, находятся в списке (или другой последовательности) lst . Когда кто-то пишет

 random.choice(lst) 

вместо этого они всегда lst на месте вместо исключения. Принцип Python, который «явный лучше, чем неявный», затем диктует, что мы должны ввести несколько дополнительных символов.

(Принято, результат random.choice("foobar") указывают другие, может быть неожиданным для новичков, но как только вы привыкнете к этому языку, вы поймете, как это работает.)

Проблема в том, что вы вызываете random.choice с 3 параметрами, а не с одним параметром с 3 элементами. Попробуйте random.choice(('one', 'two', 'three')) например.

Любая последовательность с длиной и подходящей __getitem__ (для индексирования) будет делать – поскольку она выбирает число от 0 до len(something) чтобы выбрать элемент.

Таким образом, вы могли бы использовать кортеж вместо этого, если захотите.

random.choice будет работать для любой последовательности, поддерживающей индексирование.

 >>> random.choice("foobar") #string 'o' >>> random.choice(("foo","bar","spam")) #tuple 'spam' >>> random.choice(["foo","bar","spam"]) #list 'spam' 

Не будет работать для наборов:

 >>> random.choice({"foo","bar","spam"}) 
 Traceback (most recent call last): File "<ipython-input-313-e97c3088a7ef>", line 1, in <module> random.choice({"foo","bar","spam"}) File "/usr/lib/python2.7/random.py", line 274, in choice return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty TypeError: 'set' object does not support indexing 

В random.choice("hearts" , "clubs", "frogs") вы фактически передали три аргумента по choice , в то время как random.choice ожидает только один параметр, и это тоже должно поддерживать индексирование.

Но random.choice может работать для dict, если dict имеет числовые клавиши (от 0 до len (dict) -1), так как внутри он делает что-то вроде этого:

 dic[int(random() * len(seq))] 

Пример:

 >>> dic = dict(zip([1, 2, 3, 4, 5, 6], "abcdef")) >>> random.choice(dic) 'b' >>> random.choice(dic) 'd' >>> random.choice(dic) 'd' >>> random.choice(dic) #fails as 0 was not found in dic Traceback (most recent call last): File "<ipython-input-366-5cfa0e5f2911>", line 1, in <module> random.choice(dic) File "/usr/lib/python2.7/random.py", line 274, in choice return seq[int(self.random() * len(seq))] # raises IndexError if seq is empty KeyError: 0 

Есть несколько хороших ответов выше о том, почему random.choice реализован так, как есть, и почему это на самом деле то, что вы, вероятно, хотите.

Вы можете легко обернуть его самостоятельно, если хотите, чтобы вы могли выбрать выбор с произвольным количеством аргументов:

 import random def random_choice_of_arbitrary_args(*args): return random.choice(args) 

Конечно, вы бы назвали его более кратким.

У этого есть следующее удивительное поведение:

 >>> random_choice_of_arbitrary_args([1, 2, 3]) [1, 2, 3] 

Это потому, что вы в конечном счете говорите random.choice, чтобы дать вам случайный элемент последовательности с одним элементом. Таким образом, лучшая реализация может быть:

 import random def my_choice(*args): if len(args) == 1: return random.choice(args[0]) else: return random.choice(args) 

Взгляните на реализацию . Он выбирает случайное число от 0 to len(input_sequence) а затем использует этот индекс для выбора случайного элемента.

Возможно, лучший ответ заключается в том, что в документации говорится, что ввод должен быть последовательностью.

Проще говоря, потому что это не так, как была определена функция random.choice . Я предполагаю, что решение было принято только потому, что принятие одного итерабельного аргумента – более чистая практика, чем просто переменное количество произвольных аргументов.

Поэтому определение такой функции:

 # This is (approximately) how it's actually written def choice(iterable): #choose from iterable 

чище, чем это:

 # This is kind of ugly def choice(*args): #make sure *args exists, choose from among them. 

То, как оно написано на самом деле, позволяет передать ему один единственный истребимый элемент любого типа, который является чистым и удобным. Если бы это было определено вторым способом , легко было бы random.choice([1, 2, 3]) его при использовании: кто-то мог вызвать random.choice([1, 2, 3]) и они всегда будут возвращаться [1, 2, 3] !

  • Есть ли способ использовать два условия if в списках в python
  • Первый индекс списка Python больше, чем x?
  • Python: копирование списка в списке
  • Удаление нескольких элементов из списка
  • Как назначить по значению в python
  • Создание списка из списка списков в Python
  • Подсчет положительных элементов в списке с использованием списков Python
  • Список чередования с фиксированным элементом
  • Python - лучший язык программирования в мире.