2012-12-05 43 views
0

假设我有一个嵌套列表,如下一个共享类似的功能:删除列表中的项目

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

,并假设我想从列表中删除除具有用于最大值的一个所有项目

[ ['a'],[24],214,1], [['a'],[24],3124,1] ] 
:项目分享在 item[0]

所以相同的字母,例如在前面的名单上有两个项目共享相同的信item[0]

我想删除前者,因为它的值较低,为item[2]

输出列表应该然后是:

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

您能否提供我一个紧凑的方式做到这一点?

+0

对不起。我会尽快做到这一点。 – user1718064

+0

很好地纠正:)订单是否重要? – RocketDonkey

回答

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]] 
0

如果返回的顺序并不重要,你可以尝试使用groupbyitertools到组项目(用第一个元素排序后),然后用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]] 

这个扩展了一下,如果你想保持原有的秩序,可以通过包括只有那些项目是results修改l,这将维持秩序:

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]] 
+1

代码golf:'[max(v,key = lambda item:item [2])for _,v in groupby(sorted(l),lambda item:item [0])]' – Boud

+0

@Boud哈哈,我老实说只是为了在免责声明中输入“试图混淆读取你的代码的任何人,你可以尝试......”。我会把荣耀留给你! – RocketDonkey

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会是最快的。