Поиск алгоритма слияния кортежей, содержащих повторяющиеся поля, в списке кортежей



Я пытаюсь найти лучший способ справиться с тем, что на первый взгляд кажется простой задачей в 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})
]


Иногда значение поля " alt "словаря 1-index будет таким же, как и значение поля" alt " словаря 1-index. поле ' alt ' словаря 0-индекса следующего элемента в списке. В приведенном выше примере видно, что при alt = 9 во 2-м и 3-м пунктах списка.



Когда это произойдет, я хочу объединить эти 2 кортежа в один кортеж, где значение alt 1-индексного словаря первого Кортежа будет равно значению alt 1-индексного словаря второго кортежа, эффективно "отменяя" повторяющиеся значения 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})
]


Я попробовал несколько подходов и чувствую, что здесь нужна какая-то рекурсия, но обработка последнего случая необходимости проверять последовательные кортежи и сливаться с ними заставляет меня удариться в стену. Любые предложения будут высоко оценены.
612   1  

1 ответ:

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([]))
[]

Comments

    Ничего не найдено.