如果二维列表中的某行或某列所有值都是None,如何删除该行或列
我有一个网格(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)]