我正在尝试制作一个将带有诸如以下列表的函数:

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单元格中KEY在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中
    计数+ = line [line [el]:line [el] +1] .count(事物)
TypeError:“ int”对象不可下标

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

最佳答案

这可能有点笨拙,但是列表理解始终是一种选择。

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


通过此过程,[v[i:i+2] for v in grid[j:j+2]用于创建2x2网格。如果您要对列表的整个列表执行很多次,这不是一个超级高效的操作,但是写起来很快。

要计算键,它首先用.count(key)计数每一行,然后使用sum()将其加到2x2网格中的2行的每一行中。

最后一行是您如何选择要查看的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中的列表切片不会复制数据,甚至可以追溯到Python 2.7+。 get_nxn()操作相对于grid的大小以恒定时间运行,这是一个快速的恒定时间。

07-28 02:54
查看更多