由于dict()是根据内部哈希值进行快速访问而不是按照添加元素的顺序进行排序的,因此您可以认为它足够随机并使用dict.popitem()。
但是popitem()也会从字典中删除该元素。因此,您可能希望使用:
d = {...}
keys = d.keys()
item = keys.pop(0)
value = d[item]
然而,需要注意的是,具有相同/类似键的任何字典可能具有相同的键顺序。
如果要进行适当的随机获取,请执行以下操作:
import random
d = {"red": "#ff0000", "green": "#00ff00", "blue": "#0000ff", "black": "#000000", "white": "#ffffff"}
keys = d.keys()
item = random.choice(keys)
value = d[item]
当然,如果你想要防止重复,你就必须使用额外的 dict() 和 while 循环:
import random
d = {"red": "#ff0000", "green": "#00ff00", "blue": "#0000ff", "black": "#000000", "white": "#ffffff"}
keys = d.keys()
used = {}
def get_rand_item (d):
item = random.choice(keys)
while item in used:
item = random.choice(keys)
value = d[item]
used[item] = None
return item, value
get_rand_item(d)
在这里,我使用字典作为存储方式,因为它的搜索速度比列表更快。
你要求最快的方法。 :D
顺便说一下,让我们看看是否可以获得更快的随机项获取方式而不重复:
from random import choice
class RandomGetter:
def __init__ (self, d, adapt=1):
self.keys = keys = d.keys()
if adapt:
dct = {}
for k in keys:
dct[k] = (d[k], 0)
self.dct = dct
self.count = 1
else:
self.dct = d
self.count = d[keys[0]][1]+1
self.visited = 0
self.length = len(self.dct)
def __len__ (self):
return self.length
def randitem (self, default=None):
if self.visited==self.length:
self.count += 1
self.visited = 0
return default
d = self.dct
kz = self.keys
c = self.count
key = choice(kz)
value, flag = d[key]
while flag>=c:
key = choice(kz)
value, flag = d[key]
d[key] = (value, flag+1)
self.visited += 1
return key, value
def next (self):
i = self.randitem()
if i==None: raise StopIteration
return i
def __iter__ (self):
while 1: yield self.next()
d = dict.fromkeys(xrange(1000000))
r = RandomGetter(d)
from time import time
def check ():
randitem = r.randitem
e = []
for _ in xrange(len(r)):
t = time()
randitem()
e.append(time()-t)
print "Total/min/max/med/avg/(0 time count)"
e.sort()
s = sum(e)
if len(r)%2==0: m = (e[len(r)/2]+e[len(r)/2+1])/2
else: m = e[len(r)/2+1]
print s, e[0], e[-1], m, ("%.15f" % (s/1000000)), e.count(0.0)
check()
next(iter(dct))
? - vaultah