在 Python 中对包含字典的列表进行去重并更改重复项的源数据

65 阅读3分钟

我们有一个包含字典的 Python 列表,每个字典包含两个键值对:srcwidget。我们需要从这个列表中删除重复的字典,并对剩下的重复字典的 src 数据进行更改。具体来说,我们希望将已删除的重复字典的 src 数据添加到原始字典的 src 数据中。

2、解决方案 为了解决这个问题,我们可以使用两种方法:

方法一:使用集合和列表解析

def find_widget(widget, L):
    for i, v in enumerate(L):
      if v[widget] == widget:
          return i

known_widgets= set()
processed_results = []

for x in raw_results:
    widget = x['widget']
    if widget in known_widgets:
        processed_widgets[find_widget(widget, processed_results)]['src'] += '-%s' % x['tag']
        continue
    else:
        processed_results.append(x)
        known_widgets.add(widget)

在这个方法中,我们首先定义了一个辅助函数 find_widget(),用于找到列表中给定小部件的索引。然后,我们使用集合和列表解析来遍历原始列表,并根据小部件是否在已知小部件集合中进行判断。如果小部件在已知小部件集合中,则找到其在已处理列表中的索引,并将已删除的重复字典的 src 数据添加到原始字典的 src 数据中。否则,将当前字典添加到已处理列表中,并将小部件添加到已知小部件集合中。

方法二:使用 collections.defaultdict()

class Widget(object):
    def __init__(self, desc):
        self.desc = desc
    def __str__(self):
        return "Widget(%s)" % self.desc

raw_results = [
    {'src':'tag-zip', 'widget':Widget('to complete a form today')},
    {'src':'tag-zip', 'widget':Widget('a newspaper')},
    {'src':'zip', 'widget':Widget('the new Jack Johnson album')},
    {'src':'zip', 'widget':Widget('premium dog food')}
]

from collections import defaultdict
known_widgets = defaultdict(list)
for x in raw_results:
    k, v = x['src'], x['widget']
    known_widgets[k].append(v)

for k, v in known_widgets.iteritems():
    print "%s: %s" % (k, ",".join(str(w) for w in v))

在这个方法中,我们首先定义了一个 Widget 类来表示小部件。然后,我们使用 collections.defaultdict() 来创建一个默认字典,其中键是字典的 src 数据,值是一个列表,用于存储具有相同 src 数据的小部件。然后,我们遍历原始列表,并将每个字典添加到默认字典中。最后,我们遍历默认字典,并打印每个键值对。

如果希望删除重复的小部件,我们可以使用以下代码:

from collections import defaultdict
class Widget(object):
    def __init__(self, desc):
        self.desc = desc
    def __hash__(self):
        return hash(self.desc)
    def __cmp__(self, other):
        return cmp(self.desc, other.desc)

raw_results = [
    {'src':'tag-zip', 'widget':Widget('to complete a form today')},
    {'src':'tag-zip', 'widget':Widget('a newspaper')},
    {'src':'zip', 'widget':Widget('the new Jack Johnson album')},
    {'src':'zip', 'widget':Widget('premium dog food')},
    {'src':'tag-zip', 'widget':Widget('to complete a form today')},
    {'src':'tag-zip', 'widget':Widget('a newspaper')},
    {'src':'zip', 'widget':Widget('the new Jack Johnson album')},
    {'src':'zip', 'widget':Widget('premium dog food')},
]

known_widgets = defaultdict(set)
for x in raw_results:
    k, v = x['src'], x['widget']
    known_widgets[k].add(v)

for k, v in known_widgets.iteritems():
    print "%s: %s" % (k, ",".join(str(w) for w in v))

在这个代码中,我们修改了 Widget 类,使其具有 __hash__()__cmp__() 方法,以便能够将小部件作为集合的元素。然后,我们使用 defaultdict(set) 来创建一个默认字典,其中键是字典的 src 数据,值是一个集合,用于存储具有相同 src 数据的小部件。然后,我们遍历原始列表,并将每个字典添加到默认字典中。最后,我们遍历默认字典,并打印每个键值对。