过滤列表中的两个第一个匹配元素
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了过滤列表中的两个第一个匹配元素相关的知识,希望对你有一定的参考价值。
我有一个按升序排序的列表列表,类似于这个:
input = [[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[3,1],[6,1],[6,2]]
我想过滤此列表,以便新列表只包含位置0中匹配整数的前两个(或唯一)元素,如下所示:
output = [[1,1],[1,2],[2,1],[2,2],[3,1],[6,1],[6,2]]
如果剩余元素(不符合标准的元素)将保留在输入列表中,而匹配元素将单独存储,那将是理想的。
我该怎么做呢?
先感谢您!
编辑:索引1上的元素实际上可以是任何整数,例如[[1,6],[1,7],[1,8],[2,1],[2,2]]
答案
Pandas
虽然这有点矫枉过正,但我们可以使用pandas:
import pandas as pd
pd.DataFrame(d).groupby(0).head(2).values.tolist()
与d
原始列表。然后产生:
>>> pd.DataFrame(d).groupby(0).head(2).values.tolist()
[[1, 1], [1, 2], [2, 1], [2, 2], [3, 1], [6, 1], [6, 2]]
请注意,这将返回列表的副本,而不是原始列表。此外,所有行应具有相同数量的项目。
Itertools groupby
and islice
如果按字典顺序排列列表,那么我们可以使用itertools.groupby
:
from operator import itemgetter
from itertools import groupby, islice
[e for _, g in groupby(d, itemgetter(0)) for e in islice(g, 2)]
这再次产生:
>>> [e for _, g in groupby(d, itemgetter(0)) for e in islice(g, 2)]
[[1, 1], [1, 2], [2, 1], [2, 2], [3, 1], [6, 1], [6, 2]]
由于我们将引用复制到列表中,因此它也更灵活,并且所有列表可以具有不同数量的元素(这里至少有一个)。
编辑
通过让islice
以相反的方式工作,可以获得其余的值:保留除了第一个之外的所有内容:
[e for _, g in groupby(d, itemgetter(0)) for e in islice(g, 2, None)]
然后我们获得:
>>> [e for _, g in groupby(d, itemgetter(0)) for e in islice(g, 2, None)]
[[1, 3], [1, 4], [2, 3]]
另一答案
您还可以使用collections.defaultdict
按第一个索引对子列表进行分组:
from collections import defaultdict
from pprint import pprint
input_lst = [[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[3,1],[6,1],[6,2]]
groups = defaultdict(list)
for lst in input_lst:
key = lst[0]
groups[key].append(lst)
pprint(groups)
这给了这个分组字典:
defaultdict(<class 'list'>,
{1: [[1, 1], [1, 2], [1, 3], [1, 4]],
2: [[2, 1], [2, 2], [2, 3]],
3: [[3, 1]],
6: [[6, 1], [6, 2]]})
然后你可以从每个键中取出前两个[:2]
值,并确保结果被展平并最终排序:
from itertools import chain
result = sorted(chain.from_iterable(x[:2] for x in groups.values()))
print(result)
哪个输出:
[[1, 1], [1, 2], [2, 1], [2, 2], [3, 1], [6, 1], [6, 2]]
以上是关于过滤列表中的两个第一个匹配元素的主要内容,如果未能解决你的问题,请参考以下文章