2013-04-02 2 views
2

Мне нужно сравнить 2 таблицы аналогичной схемы и иметь 2 генераторных объекта. Как я могу сравнить эти 2 генератора по строкам в Python. Необходимо реализовать логику сравнения файлов,Обработка Python для цикла

If generator-object-1 = generator-object-1: 
     then read-next-row-generator-object-1,read-next-row-generator-object-1 
elif generator-object-1 > generator-object-2: 
     then read-next-row-generator-object-2 
elif generator-object-1 < generator-object-2 
     then read-next-row-generator-object-1 

Есть ли лучший способ сделать в Python?

+0

Это похоже на слияние; находя следующее нижнее значение в двух отсортированных таблицах. Как вы планируете использовать генератор? –

ответ

0

Существует на самом деле не слишком много лучший способ ...

go1 = next(generator1) 
go2 = next(generator2) 

try: 
    while True 
     if go1 == go2: 
      go1 = next(generator1) 
      go2 = next(generator2) 
     elif go1 > go2: 
      go2 = next(generator2) 
     elif go1 < go2: 
      go1 = next(generator1) 
except StopIteration 
    pass #Done now ... 

Конечно, то, что вы описываете здесь действительно этап слияния из сортировки слияния (или, по крайней мере, как это Кажется) - Хотя вы не уступаете остальным объектам после исчерпания одного генератора. Встроенный сорт CPython очень похож на слияние (Tim-sort - это гибрид сортировки вставки и сортировки слияния). Таким образом, в этом случае, если вы не против того, список в конце концов, вы просто могли бы сделать:

import itertools as it 
sorted(it.chain(generator1,generator2)) 

и Боба твой дядя.

+0

Я в основном пытаюсь написать поле инструментом сравнения полей между 2 объектами итератора ... Объекты итератора содержат количество файлов ... Есть ли какой-нибудь инструмент Python, который уже существует? – user1050619

3

Я использовал это в прошлом:

import operator 

def mergeiter(*iterables, **kwargs): 
    """Given a set of sorted iterables, yield the next value in merged order""" 
    iterables = [iter(it) for it in iterables] 
    iterables = {i: [next(it), i, it] for i, it in enumerate(iterables)} 
    if 'key' not in kwargs: 
     key = operator.itemgetter(0) 
    else: 
     key = lambda item, key=kwargs['key']: key(item[0]) 

    while True: 
     value, i, it = min(iterables.values(), key=key) 
     yield value 
     try: 
      iterables[i][0] = next(it) 
     except StopIteration: 
      del iterables[i] 
      if not iterables: 
       raise 

Этот список элементов из данных итерируемыми в отсортированном порядке, при условии, что входные итерируемыми сами уже отсортирован.

Вышеуказанный генератор будет перебирать ваши два генератора в том же порядке, что и ваш psuedo-код.

+0

Это на самом деле аккуратно. Здесь много гимнастики, но кажется довольно солидным. Хотя 'sorted (цепочка (g1, g2, g3, ...))' все еще проще :) – mgilson

+0

@mgilson: 'sorted()' потребляет весь итератор. Это можно использовать для объединения данных * уже * отсортированных, по одному элементу за раз. Отлично подходит для внешних сортировок (сортируйте большой файл, разделив его на куски, слияние отдельных запросов к базе данных и т. Д.). –

+0

Да, я получаю это :) (+1) - И я собирался сказать, что вы можете добавить «ключ», но вы, похоже, уже сделали это. – mgilson

Смежные вопросы