[英]Remove items (sublists) from nested list based on comparison of their elements
首先發布在這里,所以我希望我不會重復任何問題(我檢查過)。
這是交易:
我有一個列表,包含4個元素子列表,例如[[10,1,3,6],[22,3,5,7],[2,1,4,7],[44,3,1,0]]
我想做的是:
1)刪除所有具有等於零的第四子元素的元素,例如[44,3,1,0]
(簡單部分)
2)刪除具有相同第二元素的項目,僅保留具有最大第一元素的項目,例如[[10,1,3,6],[2,1,4,7]] -> [10,1,3,6]
我一直試圖使用嵌套循環和第二個列表來獲取我想要保留的元素的解決方案,但我似乎無法確定它。
我可以使用優雅的解決方案嗎?
如果listA是你的原始列表,listB是你的新列表,看起來part(2)可以通過迭代listA來解決,檢查當前元素(嵌套列表)是否包含重復的第二個元素,如果是,則比較第一個看到哪個嵌套列表保留在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的評論一樣,我確信有更優雅的方式來做到這一點,但我認為這樣可以完成工作。 此外,問題並沒有說明當第一個元素相等時會發生什么,所以也需要考慮。
你可以使用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]]
如果您不關心最終列表的排序,可以按第二項排序並使用生成器查找第一項的最大值:
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]]
這是第二部分:
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)])
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.