简体   繁体   English

从列表中剥离空元素

[英]Stripping empty elements from lists

I have a python data structure like this 我有一个像这样的python数据结构

dl= [{'plat': 'unix',   'val':['', '',   '1ju', '', '',   '202', '',   '']},
     {'plat': 'Ios',    'val':['', '',   '',    '', 'Ty', '',    'Jk', '']},
     {'plat': 'NT',     'val':['', '',   1,     '', '' ,  '202', '',   '']},
     {'plat': 'centOs', 'val':['', '',   '',    '', '',   '202', '',   '']},
     {'plat': 'ubuntu', 'val':['', 'KL', '1',   '', '',   '',    '',   '9i0']}]
                                ^                ^
                                |                |
                                \                /
                                   Delete these 

I am trying to delete the position in the list 'val' where the values in the same column in each list are empty. 我试图删除列表'val'中每个列表中同一列中的值为空的位置。 For example, position 0 and 3 in the list(dl). 例如,在list(dl)中放置0和3。 I am trying to get an output like this: 我试图得到这样的输出:

Output= [{'plat': 'unix',   'val':['',   '1ju', '',   '202', '',   '']},
         {'plat': 'Ios',    'val':['',   '',    'Ty', '',    'Jk', '']},
         {'plat': 'NT',     'val':['',   1,     '' ,  '202', '',   '']},
         {'plat': 'centOs', 'val':['',   '',    '',   '202', '',   '']},
         {'plat': 'ubuntu', 'val':['KL', '1',   '',   '',    '',   '9i0']}]

Let's do this in two steps. 让我们分两步进行。 First, find indices to remove: 首先,找到要删除的索引:

lists = [e['val'] for e in dl]
idx_to_remove = [i for i, elem in enumerate(map(any, zip(*lists))) if not elem]

Second, let's filter original lists: 其次,让我们过滤原始列表:

for l in lists:
    l[:] = [elem for i, elem in enumerate(l) if i not in idx_to_remove]

Result: 结果:

>>> pprint.pprint(dl)
[{'plat': 'unix', 'val': ['', '1ju', '', '202', '', '']},
 {'plat': 'Ios', 'val': ['', '', 'Ty', '', 'Jk', '']},
 {'plat': 'NT', 'val': ['', 1, '', '202', '', '']},
 {'plat': 'centOs', 'val': ['', '', '', '202', '', '']},
 {'plat': 'ubuntu', 'val': ['KL', '1', '', '', '', '9i0']}]
dl= [{'plat': 'unix',   'val':['', '', '1ju', '', '', '202',  '',   '']},
     {'plat': 'Ios',    'val':['', '',  '',   '', 'Ty', '',     'Jk', '']},
     {'plat': 'NT',     'val':['', '',   1,   '', '' , '202', '',   '']},
     {'plat': 'centOs', 'val':['', '',  '',   '', '',  '202', '',   '']},
     {'plat': 'ubuntu', 'val':['', 'KL','1',  '', '',   '',   '',   '9i0']}]

def empty_indices(lst):
  return {i for i,v in enumerate(lst) if not v}

# Need to special-case the first one to initialize the set of "emtpy" indices.
remove_idx = empty_indices(dl[0]['val'])
# Here we do the first one twice.  We could use itertools.islice but it's 
# probably not worth the miniscule speedup.
for item in dl:
  remove_idx &= empty_indices(item['val'])

for item in dl:
    item['val'] = [k for i,k in enumerate(item['val']) if i not in remove_idx]

# print the results.
import pprint
pprint.pprint(dl)
from itertools import izip
from operator import itemgetter

# create an iterator over columns
columns = izip(*(d['val'] for d in dl))

# make function keeps non-empty columns
keepfunc = itemgetter(*(i for i, c in enumerate(columns) if any(c)))

# apply function to each list
for d in dl:
    d['val'] = list(keepfunc(d['val']))

Yet another possible solution (not really efficient but well...). 还有另一种可能的解决方案(不是很有效,但是很好...)。 zip() is really underrated... zip()确实被低估了...

# extract the values as a list of list
vals = [item["val"] for item in dl]
# transpose lines to columns
cols = map(list, zip(*lines))
# filter out empty columns
cols = [c for c in cols if filter(None, c)]
# retranspose columns to lines
lines = map(list, zip(*cols))
# build the new dict
output = [
    dict(plat=item["plat"], val=line) for item, line in zip(dl, lines)
    ]

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

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