2013-04-02 74 views
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

我基本上試圖通過兩個迭代器對象之間的字段比較工具編寫一個字段...迭代器對象包含多個文件...有沒有任何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 

這將列出從排序的順序給出iterables項目,所提供的輸入iterables本身已經排序。

上述生成器會按照僞代碼的順序迭代您的兩個生成器。

+0

這實際上很整齊。這裏有很多體操,但看起來很穩固。儘管'sorted(chain(g1,g2,g3,...))'更容易:) – mgilson

+0

@mgilson:'sorted()'消耗整個迭代器。這可以用來合併數據*已經*排序,一次一個項目。非常適合外部排序(通過將大文件拆分成塊,對單獨的數據庫查詢進行合併等)進行排序。 –

+0

是的,我明白了:)(+1) - 我正要說,你可能想添加一個「鑰匙」,但你似乎已經做到了。 – mgilson