为什么random.choice需要一个列表

Dan*_*rex 12 python list

这可能是一个非常直截了当的问题,但是为什么会喜欢简单的解释?

以下代码需要一个列表才能获得随机卡.

 import random
 card = random.choice (["hearts", "clubs", "frogs"])
Run Code Online (Sandbox Code Playgroud)

我很困惑为什么它需要一个列表,为什么我不能这样做.

import = random
card = random.choice("hearts" , "clubs", "frogs")
Run Code Online (Sandbox Code Playgroud)

我很好,我不能这样做我只是想知道为什么?

Fre*_*Foo 30

因为墨菲的定律:任何可能以错误方式完成的事情都会被某人以某种错误的方式完成.您建议的API需要

random.choice(*lst)
Run Code Online (Sandbox Code Playgroud)

当可供选择的值在列表(或其他序列)中时lst.有人写的时候

random.choice(lst)
Run Code Online (Sandbox Code Playgroud)

相反,他们总是会lst回来而不是例外."显式优于隐式"的Python原则规定我们必须输入一些额外的字符.

(承认,random.choice("foobar")其他人指出的结果对于初学者来说可能会让人感到惊讶,但是一旦你习惯了这种语言,你就会欣赏它的运作方式.)

  • +1回答OP实际问的问题(我认为). (7认同)
  • @GrijeshChauhan看看实现,它只能用数字键,因为`choice`返回`seq [int(self.random()*len(seq))]`.你只能通过`d = {"foo":1,"bar":2,"baz":3}``d [random.choice(d.keys())]`(或`d [ random.choice(在Py3中列出(d.keys()))]`. (3认同)

Jon*_*nts 8

问题是您random.choice使用3个参数调用,而不是使用3个元素调用单个参数.试试吧random.choice(('one', 'two', 'three')).

任何具有长度和适合__getitem__(用于索引)的序列都可以 - 因为它选择0之间的数字并len(something)选择元素.

所以如果你愿意,你可以使用元组代替.


Asw*_*esh 7

因为,第一个片段

["hearts","clubs","frogs"]
Run Code Online (Sandbox Code Playgroud)

只向函数发送一个参数(列表)

而第二个发送三个字符串到函数.该功能choice只能使用一个参数.因此,您必须将其作为列表或任何可以编制索引的内容发送,以便它选择随机索引来返回值

  • 这种推理是有缺陷的.如果`random.choice`采用了可变数量的参数,它将获取元组中的参数,否则行为可能完全相同. (10认同)
  • 它确实是@AswinMurugesh.你基本上是在说"`choice`需要一个参数,因为它需要一个参数",好像不可能以一种可能需要多个参数的方式创建`choice`. (6认同)
  • 任何类型的序列都可以 - 包括字符串. (4认同)
  • @AswinMurugesh:我不是说它需要多个参数.我说它如果有的话几乎没有任何区别. (4认同)
  • 但是,这并没有使我的答案有缺陷 (2认同)

Ash*_*ary 5

random.choice 适用于任何支持索引的序列.

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

套不适用:

>>> random.choice({"foo","bar","spam"})
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

random.choice("hearts" , "clubs", "frogs")您实际传递三个参数choice,而random.choice希望只有一个参数,并且也必须支持索引.

但是random.choice如果dict有数字键(介于0到len(dict)-1之间),可以为dict工作,因为在内部它做了这样的事情:

dic[int(random() * len(seq))] 
Run Code Online (Sandbox Code Playgroud)

例:

>>> 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
Run Code Online (Sandbox Code Playgroud)