根据列表中列表中的公共元素提取最大列表

时间:2019-11-23 05:35:51

标签: python list

我想知道是否有可能基于列表中列表中的公共元素提取最大列表。 我的意思是假设我们有以下列表列表:

list = [['p_1', [3, 4, 5, 6], 6.2],
        ['p_2', [3, 4, 5, 6], 8.4],
        ['p_3', [3, 7, 8, 9],9.1],
        ['p_4', [3, 4, 5, 6],8.2]]

我的计划是将每个列表中的第二个元素与其他列表中的第二个元素进行比较,然后如果第二个元素相同,则选择具有最高第三个元素的列表。例如,第一,第二和第四列表的第二个元素是相同的(即[3,4,5,6])。现在,从6.2 < 8.2 < 8.4开始,将选择第二个列表。另外,由于第三列表的第二个元素是唯一的,因此也应选择此列表。实际上,最终列表应类似于以下列表:

max_list = [['p_2', [3, 4, 5, 6], 8.4], ['p_3', [3, 7, 8, 9],9.1]] 

我使用以下代码修改了当前列表,但它不起作用。

import itertools 
for i, k in itertools.combinations(list, 2):
    if i[1]==k[1]:
        if i[3]>= k[3]:
            list.remove(k)
        else:
            list.remove(i)

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

您可以按第二个元素排序,然后使用itertools.groupby()将具有相同第二个元素的元素分组。这将为您提供所有第二个元素都相同的组。之后,可以根据第三个元素使用max()

from itertools import groupby
from operator import itemgetter

second = itemgetter(1)
third  = itemgetter(2)

max_list = [max(g, key=third) for k, g in groupby(sorted(l, key=second), key=second)]
# [['p_2', [3, 4, 5, 6], 8.4], ['p_3', [3, 7, 8, 9], 9.1]]

答案 1 :(得分:1)

您的逻辑是正确的,您几乎已经找到了解决方案。这是您的错误:

  1. 内部列表(例如['p_1', [3, 4, 5, 6], 6.2])包含三项。因此,最后一项的索引是2,而不是您在代码中编写的3。您应该写if i[2] >= k[2]:而不是if i[3] >= k[3]:
  2. 您必须先检查列表list中的元素,然后才能将其删除。如果没有,您将得到异常ValueError

根据您的逻辑,这是工作代码:

import itertools

list = [['p_1', [3, 4, 5, 6], 6.2],
        ['p_2', [3, 4, 5, 6], 8.4],
        ['p_3', [3, 7, 8, 9],9.1],
        ['p_4', [3, 4, 5, 6],8.2]]

max_list = list[:] # it is better to use a copy of the original list
for i, k in itertools.combinations(max_list, 2):
    if i[1] == k[1]:
        if i[2] >= k[2] and k in max_list:
            max_list.remove(k)
        elif i[2] < k[2] and i in max_list:
            max_list.remove(i)

print(max_list) # [['p_2', [3, 4, 5, 6], 8.4], ['p_3', [3, 7, 8, 9], 9.1]]
  

更新:对最大值进行计数,例如'p_2'= 1'p_3'= 1

counting = {}
for item in max_list:
    counting[item[0]] = max_list.count(item)

print(counting) # {'p_2': 1, 'p_3': 1}
  

更新:计数的新版本。

list = list = [['point_21', [5, 18, 19, 21], 21.25], 
    ['point_21', [5, 18, 19, 22], 22.05], 
    ['point_21', [5, 18, 20, 21], 21.25], 
    ['point_21', [5, 18, 20, 22], 22.01], 
    ['point_21', [5, 18, 21, 22], 22.058], 
    ['point_21', [5, 19, 20, 21], 21.5625], 
    ['point_21', [5, 18, 19, 21], 21.25], 
    ['point_20', [5, 17, 19, 22], 20], 
    ['point_20', [5, 16, 20, 21], 21.252], 
    ['point_20', [5, 19, 20, 22], 22.9], 
    ['point_20', [5, 1, 21, 22], 22.6], 
    ['point_20', [5, 12, 20, 21], 21.56]]

假设您上面有list。它包含12个项目。运行计算max_list的算法(即第一个代码)后,您将拥有包含11个项目的列表max_list,因为其中一个项目已被删除(重复)。

max_list = [['point_21', [5, 18, 19, 22], 22.05],
        ['point_21', [5, 18, 20, 21], 21.25],
        ['point_21', [5, 18, 20, 22], 22.01],
        ['point_21', [5, 18, 21, 22], 22.058],
        ['point_21', [5, 19, 20, 21], 21.5625],
        ['point_21', [5, 18, 19, 21], 21.25],
        ['point_20', [5, 17, 19, 22], 20],
        ['point_20', [5, 16, 20, 21], 21.252],
        ['point_20', [5, 19, 20, 22], 22.9],
        ['point_20', [5, 1, 21, 22], 22.6],
        ['point_20', [5, 12, 20, 21], 21.56]]

为此,这是计数算法:

counting = {}
points = set([item[0] for item in max_list if item[0]])

for point in points:
    counting[point] = len([1 for item in max_list if item[0]==point])

print(counting) # {'point_21': 6, 'point_20': 5}
相关问题