说我有一份清单清单:
[[0,0,0,1,2,3],[0,0,0,4,5,6],[0,0,0,0,7,8],[0,0,0,0,0,9]]
我希望最终得到一个列表,该列表会从该列表中的每个列表中删除常见的null / zero / keyword,以产生所需的输出:
[[1,2,3],[4,5,6],[0,7,8],[0,0,9]]
显然,循环遍历该列表中的每个列表,然后将其与所有其他列表进行比较,这是一个理想的答案。感谢。
答案 0 :(得分:2)
如果您要排序这些子列表,您会发现最大的子列表将需要从所有这些子列表中删除的零个数。所以只需找到max
:
x = [[0,0,0,1,2,3],[0,0,0,4,5,6],[0,0,0,0,7,8],[0,0,0,0,0,9]]
max(x)
Out[2]: [0, 0, 0, 4, 5, 6]
计算出需要丢弃多少个前导零:
from itertools import takewhile
#needlessly pedantic way of doing this
num_zeroes = len(list(takewhile(lambda p: p == 0, max(x))))
并切片:
[li[num_zeroes:] for li in x]
Out[12]: [[1, 2, 3], [4, 5, 6], [0, 7, 8], [0, 0, 9]]
答案 1 :(得分:1)
显然,循环遍历该列表中的每个列表,然后将其与所有其他列表进行比较,这是一个理想的答案。
嗯,没有办法将前缀与每个列表的前缀进行比较。
但是您可以避免将每个列表与每个列表进行比较。换句话说,你可以使这个O(NM),其中M是公共前缀的长度,而不是O(N ** 2)。只需要两遍,跟踪到目前为止在第一遍中看到的最长前缀,然后在第二遍中使用结果。
或者,我们可以使其更明确,为每个列表计算最大值的非零前缀。很明显,这是相同数量的步骤(尽管它会以较小的常数缓慢,因为它在Python中而不是在C中执行内部循环):
def first_nonzero(seq, stop=None):
for i, val in enumerate(seq):
if val or i == stop:
return i
return i
prefix = None
for lst in list_o_lists:
prefix = first_nonzero(lst, prefix)
output = [lst[prefix:] for lst in list_o_lists]