获取任意偶数维的2D列表,并返回一个包含每个2x2网格的事物计数的列表(Python)

2024-09-27 00:14:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个函数,该函数将包含如下列表:

l = [["A", 1, 2, 3, 4, 5],
     ["A", "A", 2, 3, 4, 5],
     [1, 2, 3, 4, 5, 5],
     ["A", "A", "A", "A", "A", "A"],
     ["A", 3, "A", 4, "A", "A"],
     [1, 3, 5, "A", 5, "A"]
     ]

和一个键,例如“a”。并根据每个2x2单元格中键在2D列表中出现的次数给出一个包含int的列表。例如一个函数

def count_in_grids(l, key):

会回来的

[3, 0, 0, 2, 2, 2, 1, 2, 3]

到目前为止,我写了非常糟糕的代码。我通常在处理2D列表时遇到问题。因为这实际上是一个任务,我不允许使用任何图书馆。如果有人能帮我理解和写这篇文章,我将不胜感激。你知道吗

到目前为止我写的糟糕代码:

def countInGrids(l, thing):
new_list = []  # created a final list that will be returned
count = 0
for line in range(0, len(l), 2):  # Access lines
    for el in range(0, line, 2):  # Access elements
        #count + count() of all elements in line[el] to line[el+1], 
        move 2 lines down and repeat.
        count += line[line[el]:line[el]+1].count(thing) 
        count += line+1[line[el]:line[el]+1].count(thing)

        new_list.append(count)
print(new_list)
return new_list

输出: 第63行,在countInGrids中 count+=行[line[el]:行[el]+1]。count(thing) TypeError:“int”对象不可下标

如果有人想知道,这是我第一学期的CS实验室


Tags: 函数代码in列表newfordefcount
2条回答

尝试一个简单明了的解决方案是很有诱惑力的,但我认为混淆的风险很高,可以从一个简单的解决方案开始。你知道吗

第一步是定位子正方形的所有角:

1 . 2 . 3 .
. . . . . .
4 . 5 . 6 .
. . . . . .
7 . 8 . 9 .
. . . . . .

这是一个按2计数的嵌套循环,其中角单元格位于(row, col)。你知道吗

给定一个子正方形,遍历其单元格是另一对嵌套循环,步长为1:

1 2 x . x .
3 4 . . . .
x . x . x .
. . . . . .
x . x . x .
. . . . . .

这里,每个元素位于(row + i, col + j),其中ij是内环步骤。你知道吗

在那之后,就需要编写一个条件测试,并在结果列表中为每个子平方添加一个计数器。你知道吗

最后,添加步长作为默认参数以提高可重用性。你知道吗

把它放在一起:

def count_in_grids(l, key, size=2):
    result = []

    for row in range(0, len(l), size):
        for col in range(0, len(l[row]), size):
            result.append(0)

            for i in range(size):
                for j in range(size):
                    if key == l[row+i][col+j]:
                        result[-1] += 1

    return result

print(count_in_grids(l, "A"))

这里有一个repl测试。你知道吗

这可能有点笨拙,但列表理解总是一个选择。你知道吗

def countInGrid(grid, key):
    return [sum([v[i:i+2].count(key) for v in grid[j:j+2]])
            for j in range(0, len(grid), 2) for i in range(0, len(grid[0]), 2)]

通过这个,它使用的2x2网格是[v[i:i+2] for v in grid[j:j+2]。如果你对整个列表做了很多次,这并不是一个超高效的操作,但是写起来很快。你知道吗

要对键进行计数,它首先使用.count(key)对每一行进行计数,然后使用sum()对2x2网格中的每两行进行相加。你知道吗

最后一行是如何选择要查看的2x2网格。它指定从何处开始,从何处结束。如果不想先遍历列,然后遍历行,ij的顺序很重要。你知道吗

列表理解基本上将以下所有小组件打包成一个更紧凑的语法。你知道吗

def count_row(v, key):
    return v.count(key)

def count_grid(grid, key):
    return sum(count_row(v, key) for v in grid)

def get_nxn(grid, i, j, n=2):
    return [v[i:i+n] for v in grid[j:j+n]]

def iter_block_row(grid, j):
    for i in range(0, len(grid[0]), 2):
        yield get_nxn(grid, i, j)

def iter_grid(grid):
    for j in range(0, len(grid), 2):
        # In Python 3.3+, use
        # yield from iter_block_row(grid, j)
        for g in iter_block_row(grid, j):
            yield g

def count_in_grid(grid, key):
    return [count_grid(g, key) for g in iter_grid(grid)]

把大问题看成是由小部分组成,有助于用任何经验使它们易于处理。你不需要任何额外的语法糖和语言技巧就能以一种干净的方式实现同样的目标,这也是很有帮助的。你知道吗

注意get_nxn()中的片效率非常低。这是分解问题的一种方法(我认为从概念上考虑是最简单的方法),但不是最有效的方法。你知道吗

更新我对get_nxn()效率低下的看法是错误的。看起来Python中的列表片不会复制数据,甚至可以追溯到python2.7+。相对于grid的大小,get_nxn()操作以恒定时间运行,并且在该时间是一个快速的恒定时间。你知道吗

相关问题 更多 >

    热门问题