Python 如何在嵌套结构中查找元素并返回索引

Python 如何在嵌套结构中查找元素并返回索引,python,list,random,Python,List,Random,我有一个由列表列表表示的方形网格-例如: grid = [[[9,3], [], [4]], [[10, 1, 2], [], [11,5]], [[8], [7, 6], []]] 最内层列表(单元格)的长度没有限制。网格必须包含从1到n的所有整数,其中n是给定的数字(在本例中为11),每个数字只能出现一次 我需要以统一的概率选择一个介于1和n之间的随机数,并返回该数字的位置(即对于“3”,我需要网格[0][0][1])。因为概率需要是一致的,我不能只选择一

我有一个由列表列表表示的方形网格-例如:

grid = [[[9,3], [], [4]], 
        [[10, 1, 2], [], [11,5]],
        [[8], [7, 6], []]]
最内层列表(单元格)的长度没有限制。网格必须包含从1到n的所有整数,其中n是给定的数字(在本例中为11),每个数字只能出现一次

我需要以统一的概率选择一个介于1和n之间的随机数,并返回该数字的位置(即对于“3”,我需要网格[0][0][1])。因为概率需要是一致的,我不能只选择一个随机单元,然后在单元中选择一个随机数,因为这会使选择偏向于单元中数字较少的单元中的数字


我最初的方法是生成一个介于1和n之间的随机数,然后在整个网格中查找该数。然而,网格可能变得相当大。解决这个问题的最佳方法是什么?

您可以创建dict,它将像这样映射数组

arrays_map={9:'1,1,1',3:'1,1,2'…}
n=len(数组\u map.values())
随机数=数组映射[radom.randint(0,n)]

如果必须在网格中查找多个项目,可以创建数组的映射,然后在位置字典中查找随机数。但如果你只需要在电网中找到一个数字,那么你可以通过它供电,直到找到为止

grid = [[[9,3], [], [4]], 
        [[10, 1, 2], [], [11,5]],
        [[8], [7, 6], []]]

locations = {n: (i, j, k)
    for i in range(len(grid))
    for j in range(len(grid[0]))
    for k, n in enumerate(grid[i][j])
}

print(locations)
# {
#   1: (1, 0, 1), 
#   2: (1, 0, 2), 
#   3: (0, 0, 1), 
#   4: (0, 2, 0), 
#   5: (1, 2, 1), 
#   6: (2, 1, 1), 
#   7: (2, 1, 0), 
#   8: (2, 0, 0), 
#   9: (0, 0, 0), 
#   10: (1, 0, 0), 
#   11: (1, 2, 0)
# }

rand_int = random.choice(locations.keys())
print(rand_int, locations[rand_int])
# (10, (1, 0, 0))

如果您有可变深度的嵌套数字列表,您可以执行以下操作,代码并不完美,只是为了演示这个想法

import random

grid = [[[9,3], [], [4]], 
        [[10, 1, 2], [], [11,5]],
        [[8], [7, 6], []]]


number_index_map = dict()
def create_map(grid, index_string): # you could other useful datastructure like list or tuple for storing the index_string
    for i, val in enumerate(grid):
        if isinstance(grid[i], list):
            next_index_string = "%s,%d"%(index_string, i) if len(index_string) else "%d"%(i)
            create_map(grid[i], next_index_string)
        else:
            key = "%s,%d"%(index_string, i) if len(index_string) else "%d"%(i)
            number_index_map[val] = key

create_map(grid, "")
print(number_index_map)


#test
n = 11
random_number = random.randint(1, n)
print("random number %d " % random_number)
random_number_index = number_index_map[random_number]
print("random number index %s"%random_number_index)

# to get back the number from the index string
temp = grid
list_index = random_number_index.split(",")
print("list index ", list_index)
for i in list_index:
    temp=temp[int(i)]
print(temp)

如果我能很好地理解这个问题,我建议我们可以使用递归搜索列表中的各种维度和长度,并找到一个数字及其位置:

import random

grid = [[[9,3], [], [4]], 
        [[10, 1, 2], [], [11,5]],
        [[8], [7, 6], []]]

def lookfor(num, grid, pos=[]):

    for i in range(len(grid)):

        if isinstance(grid[i], list):
            pos.append(i)
            pos2 = lookfor(num, grid[i], pos[:])
            if pos2 != pos:
                return pos2
            else:
                pos.pop()

        elif grid[i] == num:
            pos.append(i)
            return pos

    return pos

num = random.randint(1, 11)

print(num, '>', lookfor(num, grid))

为什么
random.randint
不够统一?“网格”是如何影响选择的一致性的?这个“网格”是如何填充的?它代表什么?如果性能成为一个问题,最好使用不同的数据源structure@DeepSpace我们仍然需要得到随机生成的数字的位置,所以你的问题实际上是“如何在嵌套结构中找到一个元素”,而不是“如何随机选择一个数字”,对吗?如果是,请编辑问题
,因为这会使选择偏向单元格中数字较少的数字。
,如何选择?只需为两个索引选择2个随机数(统一)。使用
grid[index1][index2]
进入索引,您将得到一个列表。现在,如果获得的列表不是空的,则从列表中随机选择一个数字。整个过程需要固定的时间(
O(1)
)。我不确定这比遍历整个网格并查找匹配项要快多少。如何快速创建数组映射?数组映射只需计算一次,它还允许您轻松地进行随机无偏差计算