0

以下のようなネストされたリストがあるとします。

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

item[2]同じ文字を共有しているアイテムの中で最大値を持つアイテムを除くすべてのアイテムをリストから削除したいとします。item[0]

たとえば、前のリストには、同じ文字を共有する2つのアイテムがありますitem[0]

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

前者は値が低いので削除したいと思いますitem[2]

その場合、出力リストは次のようになります。

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

コンパクトな方法を教えていただけますか?

4

3 に答える 3

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]]
于 2012-12-05T16:40:24.667 に答える
0

返される順序が重要でない場合は、groupbyfromitertoolsを使用してアイテムを最初の要素でグループ化し(最初の要素で並べ替えた後)、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]]
于 2012-12-05T16:45:01.903 に答える
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が一番速いと思います。

于 2012-12-05T17:05:08.727 に答える