3

ここに最初の投稿なので、質問が重複していないことを願っています(ただし、確認しました)。

契約は次のとおりです。

4 つの要素サブリストを含むリストがあります。[[10,1,3,6],[22,3,5,7],[2,1,4,7],[44,3,1,0]]

私がやりたいことは次のとおりです。

1) ゼロに等しい 4 番目のサブ要素を持つすべての要素を削除します[44,3,1,0](簡単な部分)。

2) 同じ 2 番目の要素を持つアイテムを削除し、最初の要素が最大のものだけを保持します。[[10,1,3,6],[2,1,4,7]] -> [10,1,3,6]

ネストされたループと保持したい要素を取得する 2 番目のリストを使用して解決策を見つけようとしましたが、それを釘付けにすることができないようです。

私が使用できるエレガントなソリューションはありますか?

4

4 に答える 4

2

listA が元のリストで、listB が新しいリストの場合、部分 (2) は listA を反復処理し、現在の要素 (ネストされたリスト) に重複する 2 番目の要素が含まれているかどうかを確認し、含まれている場合は比較することで解決できるようです。 listB に残っているネストされたリストを確認する最初の要素。したがって、擬似コードでは:

sizeOfListA = # whatever the original size is
sizeOfListB = 0

for i in (sizeOfListA):
  for j in (sizeOfListB):
    if listA[i][1] == listB[j][1]:  # check if second element is a duplicate
      if listA[i][0] > listB[j][0]: # check which has the bigger first element
        listB[j] = listA[i]
    else:   # if second element is unique, append nested list and increment size
      listB.append(listA[i])
      sizeOfListB += 1

それはパート (2) だけです。Burhan のコメントのように、これを行うためのよりエレガントな方法があると確信していますが、これで仕事が完了すると思います。また、質問は最初の要素が等しいときに何が起こるかを述べていないため、それも考慮する必要があります。

于 2012-10-27T14:42:21.880 に答える
2

使用できますitertools.groupby

from itertools import groupby
from operator import itemgetter as ig

data = [[10,1,3,6],[22,3,5,7],[2,1,4,7],[44,3,1,0]]

# filter and sort by main key
valid_sorted = sorted((el for el in data if el[3] != 0), key=ig(1))
# ensure identical keys have highest first element first
valid_sorted.sort(key=ig(0), reverse=True)
# group by second element
grouped = groupby(valid_sorted, ig(1))
# take first element for each key
selected = [next(item) for group, item in grouped]
print selected
# [[22, 3, 5, 7], [10, 1, 3, 6]]

またはを使用してdict

d = {}
for el in valid_sorted: # doesn't need to be sorted - just excluding 4th == 0
    d[el[1]] = max(d.get(el[1], []), el)
print d.values()
# [[10, 1, 3, 6], [22, 3, 5, 7]]
于 2012-10-27T14:43:51.050 に答える
1

これは2番目の部分です:

from itertools import product

lis = [[10, 1, 3, 6], [22, 3, 5, 7], [2, 1, 4, 7]]
lis = set(map(tuple, lis))   #create a set of items of lis
removed = set()             #it will store the items to be removed

for x, y in product(lis, repeat=2):
    if x != y:
        if x[1] == y[1]:
            removed.add(y if x[0] > y[0] else x)

print "removed-->",removed

print lis-removed       #final answer

出力:

removed--> set([(2, 1, 4, 7)])
set([(22, 3, 5, 7), (10, 1, 3, 6)])
于 2012-10-27T17:38:26.507 に答える
1

最終的なリストの順序を気にしない場合は、2 番目の項目で並べ替え、ジェネレーターを使用して最初の項目の最大値を見つけることができます。

l = [[10,1,3,6],[22,3,5,7],[2,1,4,7],[44,3,1,0]]

remove_zeros_in_last = filter(lambda x: x[3] != 0, l)

ordered_by_2nd = sorted(remove_zeros_in_last, key=lambda x: x[1])

def group_equal_2nd_by_largest_first(ll):
    maxel = None
    for el in ll:
        if maxel is None:
            maxel = el  # Start accumulating maximum
        elif el[1] != maxel[1]:
            yield maxel
            maxel = el
        elif el[0] > maxel[0]:
            maxel = el  # New maximum
    if maxel is not None:
        yield maxel     # Don't forget the last item!

print list(group_equal_2nd_by_largest_first(ordered_by_2nd))

# gives [[10, 1, 3, 6], [22, 3, 5, 7]]
于 2012-10-27T14:44:17.870 に答える