从 Python 列表中删除重复记录

Removing duplicate records from a Python list

我正在从 URL 获取数据并对该数据进行一些处理。我现在已经到了需要消除重复项的地步。下面是我的程序的输出。

{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} 
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} 
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} 
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} 
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} 
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} 
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} 
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} 
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} 
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} 
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} 
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} 
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} 
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} 
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}

我希望这是我的输出:

{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} 
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} 
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} 
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} 
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}

@Number 可以在 1-7 之间。解决这个问题的最佳方法是什么?我是否需要获取 @Number 的最大值,然后打印与我的最大值一样多的行?

您可以制作一个包含 Price @Number 和 Mw 的字典,因为 keys.Then 检查新项目是否已经在字典中。

def combine(L):
    results = {}
    for item in L:
        key = (item["Price"], item["@Number"],item["Mw"])
        if key not in results:  # combine them
            results[key] = item
    return results.values()

输出

{u'Price': 148.53, u'@Number': u'4', u'Mw': 10}
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15}
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10}
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10}

这个程序完成你的要求:

data = [
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} ,
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} ,
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} ,
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} ,
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} ,
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9},
]

result = []
for item in data:
    if item not in result:
        result.append(item)
for item in result:
    print item

输出:

{u'Price': 133.84, u'@Number': u'1', u'Mw': 10}
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15}
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10}
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10}
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}

使用 OrderedDict 来维持秩序,而 u'@Number' 作为键仅在 u'@Number' 尚未出现在字典中时才添加。

l=[{u'Price': 133.84, u'@Number': u'1', u'Mw': 10},
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15},
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10},
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10},
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9},
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10},
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15},
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10},
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10},
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9},
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10},
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15},
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10},
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10},
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}
]

from collections import OrderedDict
od = OrderedDict()
for d in l:
    num =  d["@Number"]
    if num not in od:
        od[num] = d

print(list(od.values())

[{u'@Number': u'1', u'Mw': 10, u'Price': 133.84},
{u'@Number': u'2', u'Mw': 15, u'Price': 139.09},
{u'@Number': u'3', u'Mw': 10, u'Price': 144.34},
{u'@Number': u'4', u'Mw': 10, u'Price': 148.53},
{u'@Number': u'5', u'Mw': 9, u'Price': 152.52}]

如果像您的示例中那样始终保证顺序,您可以在发现重复的 "@Number":

时简单地中断
for d in l:
    num = d["@Number"]
    if num not in od:
        od[num] = d
    else:
         break

如果你想使用max:

from itertools import islice
from operator import itemgetter

# for @Number" > 9 use lambda
#  mx = int(max(l, key=lambda x: int(x["@Number"]))["@Number"])
mx = int(max(l, key=itemgetter("@Number"))["@Number"])
print(list(islice(l,None,mx)))

另一种可能性,使用 OrderedDict:

from collections import OrderedDict

l = [{u'Price': 133.84, u'@Number': u'1', u'Mw': 10}, 
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} ,
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} ,
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9} ,
{u'Price': 133.84, u'@Number': u'1', u'Mw': 10} ,
{u'Price': 139.09, u'@Number': u'2', u'Mw': 15} ,
{u'Price': 144.34, u'@Number': u'3', u'Mw': 10} ,
{u'Price': 148.53, u'@Number': u'4', u'Mw': 10} ,
{u'Price': 152.52, u'@Number': u'5', u'Mw': 9}]

od = OrderedDict()

for d in l:
    od[d["@Number"]] = d


print(od)

结果是:

OrderedDict([('1', {'@Number': '1', 'Price': 133.84, 'Mw': 10}), ('2', {'@Number': '2', 'Price': 139.09, 'Mw': 15}), ('3', {'@Number': '3', 'Price': 144.34, 'Mw': 10}), ('4', {'@Number': '4', 'Price': 148.53, 'Mw': 10}), ('5', {'@Number': '5', 'Price': 152.52, 'Mw': 9})])

在dict中,@Number被用作key。并且因为它是一个OrderedDict,所以保留了原始列表中数字的顺序。

如果您的数据确实如您所描述的那样,并且您想排除相同的三元组,那么显而易见的解决方案是将它们转换为一个集合。由于顺序很重要,您可以使用 collections.OrderedDict 代替虚拟值 True.

您首先需要将数据转换为元组,因为字典不能用作字典键:

mytuples = [ tuple(x["Price"], x["@Number"], x["Mw"]) for x in mydata

(或者只是将数据构建为元组)。

然后:

from collections import OrderedDict
unique = OrderedDict((tup, True) for tup in mytuples) 

您现在可以使用 unique.keys() 按照出现的顺序检索您的三胞胎。

你可以为已经看过的保留一套:

seen=set()
data=[]
for e in input:
    if e["@Number"] not in seen:
        seen.add(e["@Number"])
        data.append(e)

>>> data
[{u'Price': 133.84, u'@Number': u'1', u'Mw': 10}, {u'Price': 139.09, u'@Number': u'2', u'Mw': 15}, {u'Price': 144.34, u'@Number': u'3', u'Mw': 10}, {u'Price': 148.53, u'@Number': u'4', u'Mw': 10}, {u'Price': 152.52, u'@Number': u'5', u'Mw': 9}]

如果您的数据总是有序的,并且一旦您打印了最大值,您的行就会完整,您可以这样做:

>>> input[0:max(int(e) for e in (d['@Number'] for d in input))]
[{u'Price': 133.84, u'@Number': u'1', u'Mw': 10}, {u'Price': 139.09, u'@Number': u'2', u'Mw': 15}, {u'Price': 144.34, u'@Number': u'3', u'Mw': 10}, {u'Price': 148.53, u'@Number': u'4', u'Mw': 10}, {u'Price': 152.52, u'@Number': u'5', u'Mw': 9}]