簡體   English   中英

根據元素字段從列表中刪除元素

[英]Remove elements from list based on a field of elements

我有一個元組列表,其中每個元組都有兩個項目; 第一項是字典,第二項是字符串。

all_values = [
              ({'x1': 1, 'y1': 2}, 'str1'), 
              ({'x2': 1, 'y2': 2}, 'str2'), 
              ({'x3': 1, 'y3': 2}, 'str3'),
              ({'x4': 1, 'y4': 2}, 'str1'),
             ]

我想基於元組的第二項從列表中刪除重復數據。 我編寫了這段代碼,但我想對其進行改進:

flag = False
items = []
for index, item in enumerate(all_values):
    for j in range(0, index):
        if all_values[j][1] == all_values[index][1]:
            flag = True
    if not flag:
        items.append(item)
    flag = False

並得到這個:

items = [
         ({'x1': 1, 'y1': 2}, 'str1'), 
         ({'x2': 1, 'y2': 2}, 'str2'), 
         ({'x3': 1, 'y3': 2}, 'str3')
        ]

有什么幫助嗎?

順便說一句,我試圖使用list(set(all_values))刪除重復的數據,但出現錯誤unhashable type: dict

使用另一個列表(“字符串”)來收集元組的第二個字符串項。 因此,您將有一種清晰的方法來檢查當前列表項是否重復。

在下面的代碼中,出於演示目的,我添加了一個重復的列表項(具有“ str2”值)。

all_values = [
              ({'x1': 1, 'y1': 2}, 'str1'),
              ({'x2': 1, 'y2': 2}, 'str2'),
              ({'x5': 8, 'ab': 7}, 'str2'),
              ({'x3': 1, 'y3': 2}, 'str3')
             ]

strings = []
result = []
for value in all_values:
    if not value[1] in strings:
        strings.append(value[1])
        result.append(value)

新的非重復列表將顯示在“結果”中。

您可以使用以下代碼

items = []
for item in all_values:
    if next((i for i in items if i[1] == item[1]), None) is None:
        items.append(item)
items = []
[items.append(item) for item in all_values if item[1] not in [x[1] for x in items]]
print items

面向對象的方法並不更短-而是更加直觀,可讀/可維護(IMHO)。

首先創建一個模仿元組的對象,並提供一個附加的hash()eq()函數, Set稍后將使用它們來檢查對象的唯一性。

聲明函數__repr__()用於調試目的:

class tup(object):
    def __init__(self, t):
        self.t = t

    def __eq__(self, other):
        return self.t[1] == other.t[1]

    def __hash__(self):
        return hash(self.t[1])

    def __repr__(self):
        return str(t)

# now you can declare:
all_values = [
              ({'x1': 1, 'y1': 2}, 'str1'), 
              ({'x2': 1, 'y2': 2}, 'str2'), 
              ({'x2': 1, 'y2': 2}, 'str2'), 
              ({'x3': 1, 'y3': 2}, 'str3'),
              ({'x3': 1, 'y3': 2}, 'str3')
             ]

#create your objects and put them in a list             
all_vals = []
map(lambda x: all_vals.append(Tup(x)), all_values)   


print all_vals  # [({'y1': 2, 'x1': 1}, 'str1'), ({'x2': 1, 'y2': 2}, 'str2'), ({'x2': 1, 'y2': 2}, 'str2'), ({'x3': 1, 'y3': 2}, 'str3'), ({'x3': 1, 'y3': 2}, 'str3')]  

# and use Set for uniqueness 
from sets import Set
print Set(all_vals) # Set([({'x3': 1, 'y3': 2}, 'str3'), ({'x3': 1, 'y3': 2}, 'str3'), ({'x3': 1, 'y3': 2}, 'str3')])

對於那些認為大小很重要的人來說,是另一種較短的版本;)

res = []
for a in all_values:
    if a[1] not in map(lambda x: x[1], res):
        res.append(a)
print res

如果您不關心訂購,請使用dict

formattedValues = {}
# Use with reveresed if you want the first duplicate to be kept
# Use without reveresed if you want the last duplicated
for v in reversed(allValues):
    formattedValues[ v[1] ] = v

如果排序一個問題,使用OrderedDict

from collections import OrderedDict
formattedValues = OrderedDict()
for v in reversed(allValues):
    formattedValues[ v[1] ] = v

itertools Recipes具有一個函數unique_everseen ,它將根據傳入的鍵返回傳入的iterable中唯一項的迭代器,如果您希望將結果作為列表,只需將結果傳遞給list()但如果有大量數據如果可以節省內存,最好只是進行迭代。

from itertools import ifilterfalse
from operator import itemgetter

all_values = [
    ({'x1': 1, 'y1': 2}, 'str1'),
    ({'x2': 1, 'y2': 2}, 'str2'),
    ({'x5': 8, 'ab': 7}, 'str2'),
    ({'x3': 1, 'y3': 2}, 'str3')]


def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

print list(unique_everseen(all_values, itemgetter(1)))

產量

[({'y1': 2, 'x1': 1}, 'str1'), ({'x2': 1, 'y2': 2}, 'str2'), ({'x3': 1, 'y3': 2}, 'str3')]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM