如果二维列表中的某行或某列所有值都是None,如何删除该行或列

5 投票
6 回答
10546 浏览
提问于 2025-04-15 17:30

我有一个网格(6行,5列):

grid = [
        [None, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, None, None],
        ]

我对这个网格进行了扩展,可能变成这样:

grid = [
        [{"some" : "thing"}, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, None, None],
        [None, None, None, {"something" : "else"}, None],
        [None, {"another" : "thing"}, None, None, None],
        [None, None, None, None, None],
        ]

我想要删除那些全部None的整行和整列。所以在之前的代码中,网格会变成:

grid = [
        [{"some" : "thing"}, None, None],
        [None, None, {"something" : "else"}],
        [None, {"another" : "thing"}, None],
        ]

我删除了第1、2、5行(从0开始计数)和第2、4列。

现在我删除行的方式是:

for row in range(6):
    if grid[row] == [None, None, None, None, None]:
        del grid[row] 

我还没有找到一个好的方法来删除None的列。有没有什么“pythonic”的方法可以做到这一点?

6 个回答

1

在编程中,有时候我们需要把一些数据从一个地方传到另一个地方。这就像把水从一个桶倒到另一个桶一样。为了做到这一点,我们可以使用“函数”。函数就像一个小工具,可以帮助我们完成特定的任务。

当我们调用一个函数时,就像是在告诉它:“嘿,帮我做这个事情!”函数会按照我们给它的指令去工作,然后把结果返回给我们。这样,我们就可以在程序中使用这些结果,继续进行其他操作。

在编程里,数据的传递和处理是非常重要的,因为它们决定了程序的功能和效率。理解这些基本概念后,你就能更好地编写和调试代码了。

grid = ...

# remove empty rows
grid = [x for x in grid if any(x)]
# if any value you put in won't evaluate to False
# e.g. an empty string or empty list wouldn't work here
# in that case, use:
grid = [x for x in grid if any(n is not None for n in x)]

# remove empty columns
if not grid:
  raise ValueError("empty grid")
  # or whatever, as next line assumes grid[0] exists
empties = range(len(grid[0])) # assume all empty at first
for r in grid:
  empties = [c for c in empties if r[c] is None] # strip out non-empty
if empties:
  empties.reverse() # apply in reversed order
  for r in grid:
    for c in empties:
      r.pop(c)
1

使用 zip() 函数可以把不规则的数组进行转置,也就是把行和列互换。然后再运行清理程序,最后再用 zip() 一次。

7

这不是最快的方法,但我觉得很容易理解:

def transpose(grid):
    return zip(*grid)

def removeBlankRows(grid):
    return [list(row) for row in grid if any(row)]

print removeBlankRows(transpose(removeBlankRows(transpose(grid))))

输出结果:

[[{'some': 'thing'}, None, None],
 [None, None, {'something': 'else'}],
 [None, {'another': 'thing'}, None]]

工作原理:我使用 zip 写了一个函数,用来交换行和列的位置。然后有一个第二个函数 removeBlankRows,它会删除那些所有元素都是 None(或者在布尔上下文中被认为是假的东西)的行。接着,为了完成整个操作,我先转置网格(也就是交换行和列),然后删除空行(这些空行在原始数据中其实是列),再转置一次,最后再删除空行。

如果你只想去掉 None,而不想去掉其他被认为是假的东西,可以把 removeBlankRows 函数改成:

def removeBlankRows(grid):
    return [list(row) for row in grid if any(x is not None for x in row)]

撰写回答