繁体   English   中英

Python - 删除列表列表中的空行或列

[英]Python - removing empty rows or columns in a list of lists

我想这个问题有两个部分:

  1. 从列表列表中删除一个完全为空的元素列表
  2. 如果元素始终为空,则从列表列表中的每个列表中删除某个索引处的元素。

我想避免使用 pandas 并且我确信有一些涉及列表理解的解决方案。 您可以假设列表的列表是矩形的。

例子:

鉴于:

lol = [['a',None,'c'],[None,None,None],['g',None,'i'],['j',None,None]]

(编辑 - 写“无”而不是无)

返回:

lol = [['a','c'],['g','i'],['j',None]]

也许您可以尝试这种简单的方法:

outs = []

for l in lol:
    tmp = []
    for x in l:
        if x:         # OR if x is not None:     !<--- as comment suggested.
           tmp.append(x)
    if tmp:      # skip empty list: 2nd one
       outs.append(tmp)
    
print(outs)

Output:

[['a', 'c'], ['g', 'i'], ['j', 'None']]

让它发挥作用:

matrix = [['a', 'b', 'c', '0'],
          ['0', 'None', 'x', 'y'],
          ['k', 'l', None, None],
          [0, '', '', 'x']]

def remove_empty(matrix):
    outs = []

    for l in matrix:
        tmp = []
    
        for x in l:
            if x:
                tmp.append(x)
        if tmp:      # skip empty list: 2nd one
           outs.append(tmp)
    
    return outs


print(remove_empty(matrix))

= Outputs:
[['a', 'b', 'c', '0'], ['0', 'None', 'x', 'y'], ['k', 'l'], ['x']]

使用列表理解应该有效

step1 : 在每个索引 position 处计算 None 元素

step2 :一旦元素被计数,如果在某个索引处,None 计数元素的数量等于 lol 的长度,我们将消除这些元素

from collections import Counter
# note I have change the last element of the last sub to None and not 'None' 
lol = [['a',None,'c'],[None,None,None],['g',None,'i'],['j',None, None]]

# here we count None step 1
missing_vals = Counter()
for sub in lol:
    vals = {ind:  int(not bool(val)) for ind, val in enumerate(sub)}
    counter = Counter(vals)
    missing_vals = missing_vals + counter

# step 2
out = [[a for val, a in enumerate(sub_list) if missing_vals[val] != len(lol)] 
        for sub_list in lol if any(sub_list)]
print(out)
[['a', 'c'], ['g', 'i'], ['j', None]]

您的示例 output 似乎与您在问题中所说的不匹配,所以我在这里做了一些更改。

my_list = [['a', None, 'c'], [None, None, None], ['g', None, 'i'], ['j', None, 'None']]
output_check = [['a', 'c'], ['g', 'i'], ['j', 'None']]

new_list = [[x, z] for x, y, z in my_list if x]

assert output_check == new_list

print(new_list)

>>> [['a', 'c'], ['g', 'i'], ['j', 'None']]

感谢 Prayson W. Daniel首先将此方法作为评论提交。

可能不是一个非常有效的答案,但我能想到的最好的答案,因为我认为不可能使用列表理解

for item in lol:
    for i in range(item.count(None)): item.remove(None)
for i in range(lol.count([])): lol.remove([])

listcomp 方法怎么样:

[x for x in [[y for y in z if y is not None] for z in lol] if len (x) > 0]

我不推荐这个,因为它不是真的可读。

如果您的列表不包含任何值,除了None评估为 false 您可以使用(感谢 Lucas M. Uriarte):

[[y for y in z if y is not None] for z in lol if any(z) ]

首先删除空行:

result = [row for row in lol if not all(a is None for a in row)]

交换行和列:

transpose = [list(i) for i in zip(*result)]

其次删除所有空列(转置列表中的行):

transpose= [row for row in transpose if not all(a is None for a in row)]

最后交换列/行:

result = [list(i) for i in zip(*transpose)]

这个可以清理你的列表,不管它有多嵌套

def clean_list(data):
    cleaned_list = []
    for obj in data:
        if type(obj) == list:
            sublist = clean_list(obj)  
            if sublist:
                cleaned_list.append(sublist)
        elif obj is not None:
            cleaned_list.append(obj)
    return cleaned_list

这是最有效的解决方案 - 实际上做你想做的 - 我可以想出:

def removeEmpties(lol):
  colsCnt = len(lol[0])
  emptyRow = [None]*colsCnt
  # first remove all rows containing only None elements
  lol2 = list(lst for lst in lol if lst!=emptyRow)
  # second go through by columm
  for col in range(colsCnt-1,-1,-1):
      # and now look at that column in every row
      for row in lol2:
          # if an element in the current row is not None in that column
          if row[col] is not None:
              # we do not need to look any further,
              # since this column has to remain
              break;
      else:
          # if we could not find any non-None element,
          # this column must be removed from all rows.
          for row in lol2:
              del row[col]
  return lol2

print(removeEmpties([['a' ,None,'c' ],
                     [None,None,None],
                     ['g' ,None,'i' ],
                     ['j' ,None,None]]))
                     
print(removeEmpties([['a' ,None,'c' ],
                     [None,None,None],
                     ['g' ,None,'i' ],
                     ['j' ,None,'None']]))
                     

上述代码的output为:

[['a', 'c'], ['g', 'i'], ['j', None]]
[['a', 'c'], ['g', 'i'], ['j', 'None']]

您可以在https://onlinegdb.com/g76VzPGfo看到它的实际应用

暂无
暂无

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

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