python 获取列表列表中的最后 5 个元素

python get last 5 elements in list of lists

我有一个这样的列表列表:[[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]

我想编写一个函数,它将 return: [16, 14, 12, 7, 6]: 即列表列表中的最后 5 个元素。

这是我的代码,但它根本不是 pythonic(master_list 包含上面的列表):

    def find_last_five():
        last_five = []
        limit = 5

        for sublist in reversed(master_list):
            # have to check that list is not None.
            if sublist:
                for elem in sublist:
                    last_five.append(elem)
                    limit -= 1
                    if (limit == 0):
                         return last_five

        return last_five

举个例子;我假设您列表中的项目是可迭代的或 None;

>>> import itertools

>>> lst = [[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]
>>> print list(itertools.chain(*[l for l in lst if l is not None]))[-5:]
[6, 7, 12, 14, 16]

使用 flatten 配方的替代方法:

import collections

l = [[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]    

def flatten(l):

    for el in l:
        if isinstance(el, collections.Iterable) and not isinstance(el, str):
            for sub in flatten(el):
                yield sub
        else:
            yield el


print([v for v in flatten(l) if v][-5:])     
# gives: [6, 7, 12, 14, 16]
import itertools as it

a = [[1, 2], [4, 5, 6], [], [7, 12, 14, 16]]
reversed(it.islice(it.chain.from_iterable(reversed(a)), 5))

这实际上假设 a 中没有 None。如果只是 a = filter(a, None).

我会使用 itertools 来做到这一点。像

list(itertools.chain.from_iterable(x for x in l if x is not None))[:-5]

其中 l 是您的输入列表。

您可以使用列表理解:

>>> tgt=[[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]
>>> [e for sub in tgt if sub for e in sub][-5:]
[6, 7, 12, 14, 16]

过滤掉 None。过滤掉其他非列表或元组:

>>> [e for sub in tgt if isinstance(sub, (list, tuple)) for e in sub][-5:]

如果你想要的东西不必先将整个列表列表展平,你可以从最后处理结构并向上移动,直到你得到你想要的东西:

result=[]
current=[]
it=reversed(tgt)
while len(result)<5:
    if current:
        result.append(current.pop())
        continue
    else:
        try: 
             current=next(it)
        except StopIteration:
            break

(或使用 John 1024 的

不使用外部模块:

master = [[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]
new = []
total = 5

for x in reversed(master):
    if x:
        new += list(reversed(x))[:total-len(new)]
        if total == len(new):
            break

print(new)

这会产生:

[16, 14, 12, 7, 6]

这是包含所需顺序的元素的所需列表。

换一种方法怎么样?

a = [[1, 2], [4, 5, 6], [], None, [7, 12, 14, 16]]
sum(filter(None, a), [])[-1:-6:-1]

仅因为列表中的 None 类型才需要 filter 函数。如果它只是一个列表列表,这样写会简单得多:

sum(a, [])[-1:-6:-1]

这背后的原理?我们实际上使用列表的“+”运算符来继续将列表添加到单个列表中。请注意,对于更长的列表,这不是选择(如果您选择 ;))的方式。对于中小型列表,这很好。