Given input such as:
foos = [ [], [{'a': 1}], [{'a': 1}, {'a': 2}], [{'a': 1}, {'a': 2}, {'a': None}], [{'a': 1}, {'a': 2}, {'a': None}, {'a': None}], [{'a': 1}, {'a': None}, {'a': 2}], [{'a': 1}, {'a': None}, {'a': 2}, {'a': None}], [{'a': 1}, {'a': None}, {'a': 2}, {'a': None}, {'a': None}], ]
I want a function remove_empty_end_lines
that takes a list of dicts and will remove all dicts with null values that only appear at the end of the list, not in between.
for foo in foos: print(foo) print(remove_empty_end_lines(foo)) print('\n') [] [] [{'a': 1}] [{'a': 1}] [{'a': 1}, {'a': 2}] [{'a': 1}, {'a': 2}] [{'a': 1}, {'a': 2}, {'a': None}] [{'a': 1}, {'a': 2}] [{'a': 1}, {'a': 2}, {'a': None}, {'a': None}] [{'a': 1}, {'a': 2}] [{'a': 1}, {'a': None}, {'a': 2}] [{'a': 1}, {'a': None}, {'a': 2}] [{'a': 1}, {'a': None}, {'a': 2}, {'a': None}] [{'a': 1}, {'a': None}, {'a': 2}] [{'a': 1}, {'a': None}, {'a': 2}, {'a': None}, {'a': None}] [{'a': 1}, {'a': None}, {'a': 2}]
My final solution is:
def remove_empty_end_lines(lst):
i = next(
(
i for i, dct in enumerate(reversed(lst))
if any(v is not None for v in dct.values())
),
len(lst)
)
return lst[: len(lst) - i]
I'm not going for code golf, rather for performance and readability.
In the input I've listed above, the dicts are always a length of one, butin reality the lengths can be any amount. The lengths of each dict within a list will always be the same.