2016-10-10 4 views
1

私は現在、自分自身を維持しながら、標準的な変更元から大きなディッシュのリストを半定期的に更新(同期)それに対する更新。最も簡単な説明は、おそらくされている非標準のマージ、: -新しいディクテーションのリストから順序付けされたリストを更新する(優先度マージ)

  • A追加キーとしてキャッシュされた値が含まれるように私のプログラムによって更新dictsの私自身のリスト(
  • bがいくつか定期的に送信される情報です。 (Aはもともとbと同じですが)いくつかのキーが含まれていますが、Aに追加した値はキャッシュされません。
  • keys = ['key1', 'key2']はAとbの両方のキーのリストです
  • mkey = 'mtime'は、Aとbの両方が持つ特殊なキーです。 、

基本的にはA.のキャッシュされた値を無効にAで辞書がbで辞書と一致した場合、私はb['mtime'] > A['mtime']ない限り、Aに辞書を維持する必要があります。 dictがAに表示され、bに表示されない場合は取り除きますが、bに表示されていてAに表示されていない場合はAに追加します。

私の聖なる目的は、Aのキャッシュされたキーと値のペアを一切失うことではありませんが、それを達成するには問題があります。私の現在のソリューションは、次のようになります -

def priority_merge(A, b, keys, mkey): 
    retval = [] 
    b_index = 0 
    for elemA in A: 
     if b_index >= len(b): 
      break # No more items in b 
     elemb = b[b_index] 
     minA = { k: elemA[k] for k in keys } 
     minb = { k: elemb[k] for k in keys } 
     if minA == minb: # Found a match 
      if elemA[mkey] >= elemb[mkey]: 
       retval.append(elemA) 
      else: # Check mkey to see if take b instead 
       retval.append(elemb) 
      b_index = b_index + 1 
     else: # No match, check forward by one 
      if b_index+1 >= len(b): 
       continue 
      elembplus = b[b_index+1] 
      minb = { k: elembplus[k] for k in keys} 
      if minA == minb: 
       retval.append(elemb) # This is a new element 
       if elemA[mkey] >= elembplus[mkey]: 
        retval.append(elemA) 
       else: 
        retval.append(elembplus) 
       b_index = b_index + 2 
    if b_index <= len(b): 
     retval.extend(b[b_index:]) 
    return retval 

これは私が行に複数の付加および/または欠失(b相対Aへ)を取得しない限り、正常に動作します。したがって、Aに1,2,3,5が含まれていて、bに1,2,3,4,5が含まれている場合は問題ありませんが、Aに1,2,5および1,が含まれている場合は1,2,3,4,5が表示されます。私は他のケースの下LEN(B)までの検査を行うことができ

はRETVALを作成し、そのマップに基づいて再度繰り返し処理次に、一致する要素をマッピングするAb両方を通して# No match, check forward by one、又は第一反復ようにコメントしました。これはエラーが起こりやすいようですが(私はその論理的に賢明だと確信していますが、私はそれがバグであると書いていることもかなり確信しています)。私の2つのアイデアであろうとなかろうと、この問題に取り組むのに適切なアルゴリズムを推奨してください。

+0

あなたのdict http://stackoverflow.com/questions/9835668/python-dictionary-keyswhich-are-class-objects-comparison-with-multiple-compareをハッシュし、設定を適用することができハッシュされたdictのリストに対する操作。 –

+0

ありがとう@AliSAIDOMARしかし、優先順位マージのアルゴリズムに関する私の質問には答えません。ハッシュは、比較自体をより効率的にするためのもので、比較自体に問題はありません(コード例を参照)。 –

答えて

0

私は、ハッシュ方法は、keysリストにのみ基づいて、比較を確実にするのに役立つと言ったので、交差要素(マージする要素)と差異要素を見つけることができます。

class HashedDictKey(dict): 

    def __init__(self, keys_, **kwargs): 
     super().__init__(**kwargs) 
     self.keys_ = keys_ 

    def __hash__(self): 
     return hash(tuple(sorted((k, self.get(k)) for k in self.keys_))) 

    def __eq__(self, other): 
     return hash(self) == hash(other) 

def merge(A, B): 

    to_be_added = [] 
    to_be_del = [] 
    to_be_updated = [] 

    def get(obj, it): 
     for i in it: 
      if obj == i: 
       return i 
     raise ValueError("No %s value" % obj) 

    for a, b in zip_longest(A, B): 
     if a in B: 
      to_be_updated.append(a) 
     if a not in B: 
      to_be_del.append(a) 
     if b not in A: 
      to_be_added.append(b) 

    for i in to_be_del: 
     A.remove(i) 

    for j in to_be_added: 
     A.append(j) 

    for i in to_be_updated: 
     a = get(i, A) 
     b = get(i, B) 
     if b['mtime'] > a['mtime']: 
      A.remove(a) 

here the complete snippet

関連する問題