如果子列表的第一个元素在 Python 中是唯一的,则从第一个子列表中获取前两项

Posted

技术标签:

【中文标题】如果子列表的第一个元素在 Python 中是唯一的,则从第一个子列表中获取前两项【英文标题】:Get first two items from the first sublist if first element of the sublist is unique in Python 【发布时间】:2020-11-03 03:19:53 【问题描述】:

我有一个清单:

df = [['apple', 'red', '0.2'], ['apple', 'green', '8.9'], ['apple', 'brown', '2.9'], 
      ['guava', 'green', '1.9'], ['guava', 'yellow', '4.9'], ['guava', 'light green', '2.3']]

鉴于第一个子列表的值是唯一的,我只想从第一个不同的子列表中获取前 2 个项目。

预期输出:

df = [['apple', 'red'], ['guava', 'green']]

到目前为止的代码:

dummy_list = []

for item in df:
    if item[0] not in dummy_list:        
        dummy_list.append(item[:2])

这不起作用并附加所有元素。请对此有任何帮助

【问题讨论】:

如果您有另一个用于附加结果的列表(例如result_list),这将起作用。下面的setdefault 方法可能是最好的方法。 【参考方案1】:

您可以使用defaultdict 使用键值对存储所有值,然后仅从该列表中选择第一个值。

from collections import defaultdict

df = [
    ["apple", "red", "0.2"],
    ["apple", "green", "8.9"],
    ["apple", "brown", "2.9"],
    ["guava", "green", "1.9"],
    ["guava", "yellow", "4.9"],
    ["guava", "light green", "2.3"],
]
temp = defaultdict(list)
for sub_list in df:
    temp[sub_list[0]].append(sub_list)

df = [value[0][:2] for _, value in temp.items()]

print(df)

输出:

[['apple', 'red'], ['guava', 'green']]

【讨论】:

【参考方案2】:

您可以使用itertools.groupby 并使用operator.itemgetter 作为密钥:

from itertools import groupby
from operator import itemgetter

df = [['apple', 'red', '0.2'], ['apple', 'green', '8.9'], ['apple', 'brown', '2.9'], 
      ['guava', 'green', '1.9'], ['guava', 'yellow', '4.9'], ['guava', 'light green', '2.3']]

df1 = [next(g)[:2] for k, g in groupby(df, key=itemgetter(0))]

仅供参考 itemgetter(0)lambda x: x[0] 相同,因此您也可以使用它。

【讨论】:

【参考方案3】:

当你说唯一的时候,你的意思是如果你选择了一个值,那么你就不想再选择它了吗?

如果是这样,那么 pop 可能会有用:

import random as r
df = [['apple', 'red', '0.2'], ['apple', 'green', '8.9'], ['apple', 'brown', '2.9'], 
      ['guava', 'green', '1.9'], ['guava', 'yellow', '4.9'], ['guava', 'light green', '2.3']]

total = len(df)

targetdf = []

for value in range(2):
    position = r.randint(0,total-1)
    targetdf.append(df.pop(position)[:2])
    total-=1

#print(targetdf)

#[['apple', 'green'], ['guava', 'yellow']]

这段代码所做的是它在原始列表中选择一个随机位置,然后将其弹出。然后将该值保存到新列表中。

【讨论】:

【参考方案4】:

或者更聪明:使用 dict 和 setdefault 仅为第一个添加映射

result = 
for value in df:
    result.setdefault(value[0], value[:2])
result = list(result.values())

print(result)

或者您可以保留添加键的计数以避免重复它们(在单独的列表中)

keys = set()
result = []
for value in df:
    if value[0] not in keys:
        result.append(value[:2])
        keys.add(value[0])

print(result) # [['apple', 'red'], ['guava', 'green']]

【讨论】:

这是setdefault 的绝佳用例。

以上是关于如果子列表的第一个元素在 Python 中是唯一的,则从第一个子列表中获取前两项的主要内容,如果未能解决你的问题,请参考以下文章

Python元组列表将第二个元素与唯一的第一个元素合并

从列表创建组合,如果子字符串到分隔符字符位于列表项的 1 个以上的子元素中,则从列表中删除

列表python中每个唯一元素的所有索引

python列表

python切片:使用列表的一部分

如果子字符串列表中的任何值包含在数据框中的任何列中,则过滤行