问题描述
|
我知道如何从带有
random.choice(seq)
的列表中选择一个随机项,但是我如何知道该元素的索引?
解决方法
您可以先选择一个随机索引,然后在该位置获取list元素以同时拥有索引和值。
>>> import random
>>> a = [1,2,3,4,5]
>>> index = random.randint(0,len(a)-1)
>>> index
0
>>> a[index]
1
,import random
l = [\'a\',\'b\',\'c\',\'d\',\'e\']
i = random.choice(range(len(l)))
print i,l[i]
,如果值在序列中是唯一的,则可以始终说:list.index(value)
,最优雅的方法是random.randrange:
index = random.randrange(len(MY_LIST))
value = MY_LIST[index]
一个人也可以在python3中用range.object的random.choice不太优雅(但仍然比.index
好):
index = random.choice(range(len(MY_LIST)))
value = MY_LIST[index]
唯一有效的解决方案是此解决方案和random.randint
解决方案。
使用list.index
的函数不仅速度较慢(每次查找O(N)
,而不是O(1)
;如果对每个元素执行此操作会很糟糕,则必须进行O(N^2)
比较),而且如果列表列出,结果也会倾斜/不正确元素不是唯一的。
有人会认为这很慢,但事实证明它只比另一种正确的解决方案“ 7”稍慢,并且可能更具可读性。我个人认为它更优雅,因为不必像randint(0,len(...)-1)
那样进行数值索引摆弄和使用不必要的参数,但是有些人可能会认为这是一项功能,尽管一个人需要了解包含范围的randint
约定。 [start,stop]
。
random.choice的速度证明:起作用的唯一原因是对range
对象进行了索引优化。作为证明,你可以做random.choice(range(10**12))
;如果在整个列表中进行迭代,则计算机的爬网速度将变慢。
编辑:我已经忽略了randrange,因为文档似乎在说“不要使用此函数”(但实际上是指“此函数是pythonic,请使用它”)。感谢martineau指出这一点。
您当然可以将其抽象为一个函数:
def randomElement(sequence):
index = random.randrange(len(sequence))
return index,sequence[index]
i,value = randomElement(range(10**15)) # try THAT with .index,heh
# (don\'t,your machine will die)
# use xrange if using python2
# i,value = (268840440712786,268840440712786)
,您可以使用随机模块中的randrange函数来执行此操作
import random
l = [\'a\',\'e\']
i = random.randrange(len(l))
print i,l[i]
,如建议的那样使用randrage()是获取索引的好方法。通过创建通过理解创建的字典,您可以将该代码缩减为一行,如下所示。请注意,由于该字典只有一个元素,因此当您调用popitem()时,您会在一个元组中获得组合的索引和值。
import random
letters = \"abcdefghijklmnopqrstuvwxyz\"
# dictionary created via comprehension
idx,val = {i: letters[i] for i in [random.randrange(len(letters))]}.popitem()
print(\"index {} value {}\" .format(idx,val))