假设
如果我们可以假设我们想要保留的 int 将始终是每个元组中的最后一个元素,那么这很容易。我们将过滤除最后一个元素之外的所有内容,并使用结果重建一个元组。
>>> [tuple(list(filter(lambda x: not isinstance(x, int), l[:-1])) + [l[-1]]) for l in mylist]
[('a', 'b', 'c', 3), ('d', 'e', 2), ('f', 'g', 'h', 'i', 4)]
>>>
减少假设
但是,如果正如您的问题中最初指定的那样,我们只想摆脱所有整数... 除了最后一个,我们不知道事情会发生什么顺序或位置在?
首先是一个可能提供方便的函数:
>>> def partition(pred, lst):
... t, f = [], []
... for x in lst:
... (t if pred(x) else f).append(x)
... return (t, f)
...
>>>
我们可以轻松地将您的数据划分为整数而不是整数:
>>> partition(lambda x: isinstance(x, int), mylist[0])
([1, 2, 3], ['a', 'b', 'c'])
>>> [partition(lambda x: isinstance(x, int), lst) for lst in mylist]
[([1, 2, 3], ['a', 'b', 'c']), ([1, 2], ['d', 'e']), ([1, 2, 3, 4], ['f', 'g', 'h', 'i'])]
>>>
那么我们只需要丢弃除最后一个整数之外的所有整数,但是我们怎么知道在哪里将它们重新组合在一起?好吧,如果我们先枚举它们...
>>> [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]
[([(1, 1), (3, 2), (5, 3)], [(0, 'a'), (2, 'b'), (4, 'c')]), ([(1, 1), (3, 2)], [(0, 'd'), (2, 'e')]), ([(1, 1), (3, 2), (5, 3), (7, 4)], [(0, 'f'), (2, 'g'), (4, 'h'), (6, 'i')])]
>>>
现在我们只丢弃除最后一个 int 之外的所有内容,并将其添加回非 int 列表中以创建单个列表。
>>> [(i[-1], ni) for i, ni in [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]]
[((5, 3), [(0, 'a'), (2, 'b'), (4, 'c')]), ((3, 2), [(0, 'd'), (2, 'e')]), ((7, 4), [(0, 'f'), (2, 'g'), (4, 'h'), (6, 'i')])]
>>> [ni + [i[-1]] for i, ni in [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]]
[[(0, 'a'), (2, 'b'), (4, 'c'), (5, 3)], [(0, 'd'), (2, 'e'), (3, 2)], [(0, 'f'), (2, 'g'), (4, 'h'), (6, 'i'), (7, 4)]]
>>>
如果我们按照我们添加的索引进行排序 enumerate:
>>> [sorted(ni + [i[-1]], key=lambda x: x[0]) for i, ni in [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]]
[[(0, 'a'), (2, 'b'), (4, 'c'), (5, 3)], [(0, 'd'), (2, 'e'), (3, 2)], [(0, 'f'), (2, 'g'), (4, 'h'), (6, 'i'), (7, 4)]]
>>>
现在我们需要丢弃索引并转换回元组。
>>> [tuple(map(lambda x: x[1], sorted(ni + [i[-1]], key=lambda x: x[0]))) for i, ni in [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]]
[('a', 'b', 'c', 3), ('d', 'e', 2), ('f', 'g', 'h', 'i', 4)]
>>>
现在,即使我们更改输入数据,我们也只保留最后一个 int,以及它原来的位置:
>>> mylist = [('a',1,'b',2,'c',3,'d',6,'e','f'), ('d',1,'e',2),('f',1,'g',2,'h',3,'i',4)]
>>> [tuple(map(lambda x: x[1], sorted(ni + [i[-1]], key=lambda x: x[0]))) for i, ni in [partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist]]
[('a', 'b', 'c', 'd', 6, 'e', 'f'), ('d', 'e', 2), ('f', 'g', 'h', 'i', 4)]
>>>
上面表达式中的内部列表推导可以用生成器表达式替换,解决方案仍然有效。
>>> mylist = [('a',1,'b',2,'c',3,'d',6,'e','f'), ('d',1,'e',2),('f',1,'g',2,'h',3,'i',4)]
>>> [tuple(map(lambda x: x[1], sorted(ni + [i[-1]], key=lambda x: x[0]))) for i, ni in (partition(lambda x: isinstance(x[1], int), enumerate(lst)) for lst in mylist)]
[('a', 'b', 'c', 'd', 6, 'e', 'f'), ('d', 'e', 2), ('f', 'g', 'h', 'i', 4)]
>>>