删除列表中共享相似功能的项目

时间:2012-12-05 16:15:33

标签: python list

假设我有一个嵌套列表,如下所示:

[[['a'],[24],214,1] ,[['b'],[24],312,1] ,[['a'],[24],3124,1] , [['c'],[24],34,1]]

并且假设我想要从列表中删除除item[2]

中共享相同字母的项目中item[0]的最大值之外的所有项目

例如,在上一个列表中,我有两个项目在item[0]中共享相同的字母:

[ ['a'],[24],214,1], [['a'],[24],3124,1] ]

我希望删除前者,因为item[2]的值较低。

输出列表应为:

[ [['b'],[24],312,1] ,[['a'],[24],3124,1] , [['c'],[24],34,1] ]

你能建议我一个紧凑的方法吗?

3 个答案:

答案 0 :(得分:0)

由于您的问题令人困惑,我已经有可能删除最大和最小元素

>>> def foo(some_list, fn = max):
    #Create a dictionary, default dict won;t help much as 
    #we have to refer back to the value for an existing key
    #The dictionary would have item[0] as key
    foo_dict = dict()
    #Iterate through the list
    for e in some_list:
            #Check if the key exist
        if e[0][0] in foo_dict:
                    #and if it does, find the max of the existing value and the 
                    #new element. The key here is the second item
            foo_dict[e[0][0]] = fn(foo_dict[e[0][0]], e, key = lambda e:e[2])
        else:
                    #else consider the new element as the current max
            foo_dict[e[0][0]] = e
    return foo_dict.values()

>>> foo(somelist)
[[['a'], [24], 3124, 1], [['c'], [24], 34, 1], [['b'], [24], 312, 1]]
>>> foo(somelist,min)
[[['a'], [24], 214, 1], [['c'], [24], 34, 1], [['b'], [24], 312, 1]]

答案 1 :(得分:0)

如果返回的订单无关紧要,您可以尝试使用groupby中的itertools按照第一个元素(按第一个元素排序后)对项目进行分组,然后拉出最大值使用max函数(同样,应该注意这会返回一个新列表,而不是在适当的位置修改):

In [1]: from itertools import groupby

In [2]: l = [[['a'],[24],214,1] ,[['b'],[24],312,1] ,[['a'],[24],3124,1] , [['c'],[24],34,1]]

In [3]: result = []

In [4]: for k, g in groupby(sorted(l, key=lambda x: x[0]), key=lambda x: x[0]):
   ...:     result.append(max(g, key=lambda m: m[2]))
   ...:
   ...:

In [5]: result
Out[5]: [[['a'], [24], 3124, 1], [['b'], [24], 312, 1], [['c'], [24], 34, 1]]

稍微扩展一下,如果您想保持原始订单,可以修改l,只包含results中的项目,这些项目将维持订单:

In [6]: l = [i for i in l if i in result]

In [7]: l
Out[7]: [[['b'], [24], 312, 1], [['a'], [24], 3124, 1], [['c'], [24], 34, 1]]

要把它组合成一个真正可憎的单行,你可以(但可能不应该:))这样做:

In [10]: l = [[['a'],[24],214,1] ,[['b'],[24],312,1] ,[['a'],[24],3124,1] , [['c'],[24],34,1]]

In [11]: [i for i in l if i in [max(g, key=lambda m: m[2]) for k, g in groupby(sorted(l, key=lambda x: x[0]), key=lambda x: x[0])]]
Out[11]: [[['b'], [24], 312, 1], [['a'], [24], 3124, 1], [['c'], [24], 34, 1]]

答案 2 :(得分:0)

保留原始订单的一些选项,只删除比较器值低于最大值的任何项目。

def filter1(items):
    first = set(item[0][0] for item in items)
    compare = dict((f, max(item[2] for item in items if item[0][0] == f)) 
        for f in first)
    return  [item for item in items if item[2] >= compare[item[0][0]]]

def filter2(items):
    compare = {}
    for item in items:
        if ((item[0][0] in compare and item[2] > compare[item[0][0]])
            or (not item[0][0] in compare)):
            compare[item[0][0]] = item[2]
    return [item for item in items if item[2] >= compare[item[0][0]]]

def filter3(items):
    return [i for i in items if i[2] >= 
        max(j[2] for j in items if j[0][0]==i[0][0])]
如果你有一个大的列表,

filter3是最短但最慢的。我想filter2将是最快的。