从“非均匀”Python字典中选择随机元素

Bla*_*cho 5 python random dictionary

我有一个 python 字典,其中值是整数列表:

key1 -> [1, 2, 3]
key2 -> [1, 2, 3, ... 17]
key3 -> [1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)

我想选择一个随机元组(key, val),其中val是值列表中的随机值(例如:key2, 8)。随机选择在所有值中必须是统一的,因此,例如,此方法是不统一的:

random_key = random.choice(d.keys())
random_val = random.choice(d[random_key])
Run Code Online (Sandbox Code Playgroud)

因为列表的长度不一样。我知道列表串联的长度 n,所以我当前的方法如下:

idx = np.random.randint(n)
c = 0
found = False

for k in D:
    for v in D[k]:
        if c == idx:
            found = True
            do_something_with_val(k, v);
            break
        c += 1
    if found:
        break
Run Code Online (Sandbox Code Playgroud)

我的问题是:有更好/更快的方法吗?

she*_*heh 2

您可以尝试(在Python 3\xe2\x80\x94中对于Python\xc2\xa02,使用iteritems()):

\n\n
idx = random.randint(0, n)\nfor k, v in D.items():\n    if idx < len(v):\n        do_something_with_val(k, v[idx])\n        break\n    else:\n        idx -= len(v)\n
Run Code Online (Sandbox Code Playgroud)\n\n

测速:

\n\n
def ref():\n    idx = random.randint(0, n)\n    c = 0\n    found = False\n    for k in D:\n        for v in D[k]:\n            if c == idx:\n                found = True\n                # do_something_with_val(k, v);\n                break\n            c += 1\n        if found:\n            break\n\n\ndef uut():\n    idx = random.randint(0, n)\n    for k, v in D.items():\n        if idx < len(v):\n            # do_something_with_val(k, v[idx])\n            break\n        else:\n            idx -= len(v)\n\n\nif __name__ == \'__main__\':\n    print(timeit.timeit(\'ref()\', setup="from __main__ import ref", number=1000))\n    print(timeit.timeit(\'uut()\', setup="from __main__ import uut", number=1000))\n
Run Code Online (Sandbox Code Playgroud)\n\n

结果:

\n\n
1.7672173159990052\n0.011254642000494641\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用小D像检查了分布{\'key2\': [3, 4, 5], \'key1\': [0, 1, 2]}检查了分布,分布看起来对我来说很好:

\n\n
0,166851\n1,166141\n2,166269\n3,167094\n4,167130\n5,166515\n
Run Code Online (Sandbox Code Playgroud)\n