我有一个列表,其中包含以下安排:每个子列表中有N
个子列表和N_i
个子子列表,其中N_i
不一定在整个子列表中相等。每个子子列表包含两个元素(对于所有子子列表都是如此)。这就是这样一个列表的简短版本,有3个子列表和4个,3个,5个和1个子子列表:
a = [[[0.3, 1.2], [0.3, 2.3], [0.3, 4.6], [0.3, 3.4]], [[0.6, 4.5], [0.6, 2.5], [0.6, 7.8]], [[0.2, 1.4], [0.2, 6.3], [0.2, 5.2], [0.2, 2.1], [0.2, 3.6]], [[0.4, 1.3]]]
我需要一种方法从所有可用的子列表中选择一个随机的子子列表,并存储指向它的索引。
我可以使用random.choice并执行:
import random.choice as r_c
s_s_list = r_c(r_c(a))
print s_s_list
[0.6, 7.8]
这有效地返回了所有可用的随机子列表,但它有以下问题:
a-它没有给我指向它的i,j
索引(在这种情况下:[1, 2]
)并且我不能直接使用a.index(s_s_list)
因为它是< em>子子列表和
b-因为我需要重复此过程M
次来获取M
随机不同子子列表(以及指向它们的索引)不行。
c-正如评论中指出的那样,这使得被选择到具有更少元素的子列表内的子子列表的概率更高,并且我需要以相同的概率选择每个子子列表
答案 0 :(得分:2)
只需使用random.randint()
:
i = random.randint(0, len(a) - 1)
j = random.randint(0, len(a[i]) - 1)
例如:
>>> a = [[[0.3, 1.2], [0.3, 2.3], [0.3, 4.6], [0.3, 3.4]], [[0.6, 4.5], [0.6, 2.5], [0.6, 7.8]], [[0.2, 1.4], [0.2, 6.3], [0.2, 5.2], [0.2, 2.1], [0.2, 3.6]], [[0.4, 1.3]]]
>>>
>>> import random
>>> i = random.randint(0, len(a) - 1)
>>> j = random.randint(0, len(a[i]) - 1)
>>>
>>> a[i][j] # <-- this is the actual random element
[0.2, 2.1]
重要提示:上面的代码类似于您选择随机元素的代码。 然而,并非所有子子列表都有相同的机会通过此方法获取。例如,考虑:
[[l1, l2, l3, l4, l5, ...], [l0]]
在这种情况下,第一个子列表中的每个子子列表被选中的可能性很小,因为我们必须首先选择i
的第一个子列表然后然后选择它为j
的正确的子子列表。相比之下,l0
有50%的机会被挑选,因为我们必须做的就是选择i
的第二个子列表,此时唯一的选择是选择l0
j
。
您的问题编辑会稍微改变一些事情,因为您确实需要选择M
唯一的子子列表。现在,您可以使用random.sample()
尝试此操作:
>>> from random import sample
>>>
>>> M = 4
>>>
>>> random.sample([(i,j) for i in range(len(a)) for j in range(len(a[i]))], M)
[(1, 1), (2, 3), (2, 4), (1, 0)]
在Python 2.x中,使用xrange()
代替range()
。
请注意,使用此方法,每个子子列表 都有相同的机会被选中。
我们在这里做的主要是用
创建一个“索引列表”[(i,j) for i in range(len(a)) for j in range(len(a[i]))]
包含平面列表中每个子子列表的索引:
>>> [(i,j) for i in range(len(a)) for j in range(len(a[i]))]
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0)]
然后我们从此列表中进行采样,获得所需的结果。
答案 1 :(得分:2)
要跟踪索引,您可以(a)随机选择索引,并使用它们来检索子子列表;或(b)使用enumerate
将指数纳入您的清单。
由于您希望在没有替换的情况下进行抽样(即M
不同子子列表),请使用random.sample
代替M
调用{{1} }}。要在具有相同概率的子列表中进行选择,您必须首先“展平”列表。在添加索引的同时很容易做到这一点。
以下是使用random.choice
:
enumerate