寻找在元组列表中合并包含重复字段的元组的算法

时间:2014-01-14 02:47:04

标签: python algorithm list

我正试图找到最好的方法来处理python 2.7中表面上看起来很简单的任务。

我有一个包含元组的列表 每个元组包含2个字典,每个字典有2个字段:'alt'和'id'。 “id”对于列表中的每个项目始终是相同的,并且对于此问题基本上被忽略。

它看起来像这样:

[
  ({id:1, alt: 10},{id:1, alt: 12}),
  ({id:1, alt: 8},{id:1, alt: 9}),
  ({id:1, alt: 9},{id:1, alt: 10})
]

有时,1索引字典的'alt'字段的值将与列表中下一项的0索引字典的'alt'字段的值相同。在上面的示例中,您可以看到列表中第2和第3项中的alt = 9。

当发生这种情况时,我想将这两个元组合并为一个元组,其中第一个元组的1索引字典的alt值将等于第二元组的1索引字典的alt值,实际上“取消“重复的alt值:

由此:

[
  ({id:1, alt: 8},{id:1, alt: 9}),
  ({id:1, alt: 9},{id:1, alt: 10})
]

到此:

[
  ({id:1, alt: 8},{id:1, alt: 10})
]

但是,有时候列表中的多个元组会出现这种模式,因此需要在多个元组中进行合并:

由此:

[
  ({id:1, alt: 8},{id:1, alt: 9}),
  ({id:1, alt: 9},{id:1, alt: 9}),
  ({id:1, alt: 9},{id:1, alt: 10}),
  ({id:1, alt: 10},{id:1, alt: 7}),
  ({id:1, alt: 8},{id:1, alt: 9}),
  ({id:1, alt: 9},{id: 1, alt: 10})
]

到此:

[
  ({id:1, alt: 8},{id:1, alt: 7}),
  ({id:1, alt: 8},{id:1, alt: 10})
]

我已经尝试了几种方法,并且觉得这里需要某种递归,但是处理后一种需要检查连续元组并在它们之间合并的情况导致我碰壁。任何建议都会非常感激。

1 个答案:

答案 0 :(得分:2)

def merge(xs):
    it = iter(xs)
    ret = next(it, (None, None))
    for x in it:
        if ret[1] is None or x[0]['alt'] != ret[1]['alt']:
            yield ret
            ret = x
        else:
            ret = ret[0], x[1]
    if ret[0] is not None:
        yield ret

示例:

>>> data = [
...     ({'id':1, 'alt': 8}, {'id':1, 'alt': 9}),
...     ({'id':1, 'alt': 9}, {'id':1, 'alt': 9}),
...     ({'id':1, 'alt': 9}, {'id':1, 'alt': 10}),
...     ({'id':1, 'alt': 10}, {'id':1, 'alt': 7}),
...     ({'id':1, 'alt': 8}, {'id':1, 'alt': 9}),
...     ({'id':1, 'alt': 9}, {'id': 1, 'alt': 10})
... ]
>>> list(merge(data))
[({'alt': 8, 'id': 1}, {'alt': 7, 'id': 1}),
 ({'alt': 8, 'id': 1}, {'alt': 10, 'id': 1})]

>>> data = [
...   ({'id':1, 'alt': 10}, {'id':1, 'alt': 12}),
...   ({'id':1, 'alt': 8}, {'id':1, 'alt': 9}),
...   ({'id':1, 'alt': 9}, {'id':1, 'alt': 10})
... ]
>>> list(merge(data))
[({'alt': 10, 'id': 1}, {'alt': 12, 'id': 1}),
 ({'alt': 8, 'id': 1}, {'alt': 10, 'id': 1})]

>>> list(merge([]))
[]