简体   繁体   English

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

[英]how to find an element in a nested structure and return index

I have a square grid represented by a list of list of lists - for example:我有一个由列表列表表示的方形网格 - 例如:

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

There is no limit on the lengths of the innermost lists (cells).最里面的列表(单元格)的长度没有限制。 The grid must contain all integers from 1 to n, where n is a given number (in this case, 11), and each number can only appear once.网格必须包含从 1 到 n 的所有整数,其中 n 是给定的数字(在本例中为 11),并且每个数字只能出现一次。

I need to select a random number between 1 and n with uniform probability and return the location of the number (ie for '3' I would need grid[0][0][1]).我需要以均匀的概率在 1 和 n 之间选择一个随机数并返回该数字的位置(即对于“3”,我需要 grid[0][0][1])。 Because the probability needs to be uniform, I can't just select a random cell, and then select a random number in the cell, because that would bias the selection towards numbers in cells with fewer numbers in them.因为概率需要统一,所以我不能只选择一个随机单元格,然后在单元格中选择一个随机数,因为这会使选择偏向于数字较少的单元格中的数字。

My initial approach has been to generate a random number between 1 and n, and then look through the entire grid for the number.我最初的方法是生成一个介于 1 和 n 之间的随机数,然后在整个网格中查找该数字。 However, the grid can become quite big.但是,网格可能会变得非常大。 What is a more optimal approach to this problem?解决这个问题的更优化方法是什么?

If you have to find a number of items in the grid, you can create a map of the array and then just lookup the random number in the locations dictionary.如果您必须在网格中查找多个项目,您可以创建一个数组映射,然后在locations 字典中查找随机数。 But if you're only ever going to need to find a single number in a grid, then you can just power through it until you find it.但是,如果您只需要在网格中找到一个数字,那么您可以通过它直到找到它为止。

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))

You can create dict that will map your array of arrays like this您可以创建 dict 来映射这样的数组数组

arrays_map = {9:'1,1,1', 3: '1,1,2'...}
n = len(arrays_map.values())
random_number = arrays_map[radom.randint(0, n)]

If you have variable depth of nested list of numbers, you can do the following, the code is not perfect, just to demonstrate the idea如果你有可变深度的嵌套数字列表,你可以这样做,代码并不完美,只是为了演示这个想法

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)

If I am understanding the question well, I suggest that we can use recursion to search various dimensions and lengths in the list and locate a number and it's position:如果我很好地理解了这个问题,我建议我们可以使用递归来搜索列表中的各种维度和长度,并找到一个数字及其位置:

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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM