2015-11-23 20 views
5

これは私が本当に解決しやすいと思われる奇妙な問題です。私は私の家のリモートプレイヤー用の歌詞webappを構築しています。現在、再生中の曲を含むプレイヤーの辞書を生成します。例:値が同じ場合に辞書キーをマージする

{ 
    'bathroom': <Song: Blur - Song 2>, 
    'bedroom1': <Song: Blur - Song 2>, 
    'kitchen': <Song: Meat Loaf - I'd Do Anything for Love (But I Won't Do That)>, 
} 

場合によっては、これらのプレーヤーのサブセットが同期されます。上記のように、それらは同じ値を表示します。 これらをインタフェースにグループ化したいと思います。私は辞書を構築しているときに私はもっと知的になるかもしれませんが、私はそれをしないと仮定して、キーを値でマージする良い方法はありますか?

上から所望の出力は次のようになり

、のようなもの:

{ 
    'bathroom,bedroom1': <Song: Blur - Song 2>, 
    'kitchen': <Song: Meat Loaf - I'd Do Anything for Love (But I Won't Do That)>, 
} 

しかし、これは私がそれ故にこれは、私は名前で指定したいのですが(物事を見たいのですがどのように壊れるん辞書)...値ごとに複数のキーを持つことができ、重複がマージされたとき(およびそれらのすべてのキーを参照しているとき)を示すより優れたコレクションがありますか?


これは、曲の鍵と値のプレーヤーのリストにこれを反転させる良い答えがあります。これは素晴らしいことですが、時には指定のプレーヤーでどの曲が再生されているかを知りたい場合があります。だから私はもともと辞書を持っていたのです。

双方向での検索を維持する良い方法はありますか(両方のコレクションを保持するのには不十分です)?

+2

なぜ構造を逆転させないのですか?曲はユニークなので、ここの鍵にすることができますか? – Cyrbil

+1

^正確に:)低代理人の問題 – Cyrbil

+0

申し訳ありません。私は私が私の答えを更新している間に削除したので、私は質問を誤解していると思った - しかし、それは今戻ってきた。 –

答えて

2

関連するデータ量が重要な場合、これはリレーショナルデータベースが便利な形式です。キーと値の2つの列とキー列のインデックスを持つデータベースは、dictのように動作します。しかし、効率的な逆引きを可能にするために、値列にインデックスを付けることもできます。

あなたのケースでは、関連するデータ量が少ないので、defaultdictとし、(value, key)のペアを追加します。

reverse_lookup = defaultdict(list) 
for k, v in now_playing.items(): 
    reverse_lookup[v].append(k) 

そして、','.join()の値を合成キーを生成することができます。これらのコンポジットキーはディスプレイのために使用されるため、実際は検索のためではないようです。私は元のdictと逆引き参照dictの両方をメモリに保持し、どちらかを使用してください。do doルックアップを実行します。与えられたものと同じ曲を演奏している他のプレイヤーを見つけ出すという作業は、順方向と逆方向の2つの検索を必要としますが、追加コストが最小限になるようにハッシュテーブルのルックアップです。これを行うには、他の、より「面白い」方法についていくつかの考えの後


:あなたはあなたのニーズを満たすためにdisjoint set data structureを曲げることができるかもしれません。各プレイヤーのノードと、現在再生されている各曲のノードがあります。ノードは、ソングのノードとソングを現在再生しているすべてのプレイヤーのノードの両方を含むソングによってセットにグループ化されます。サイクリックリンクリストに各セットのノード(ソングとプレイヤー)を配置すると、全体のデータ構造が適切に維持されている限り、任意のノードから開始してリストを歩いて、ソングとプレイヤーのリストの両方を反復することができますその曲を再生しています。

もちろん、全体的なデータ構造を維持する、すなわち曲が変更されるときに循環リストを更新する効率的な方法を見つけることができます。プレイヤーが本当に同期されている場合、プレイヤーグループ全体が次のトラックに移動するたびに、ある曲ノードを別の曲ノードに置き換えるのは簡単です。しかし、あなたが構築しているアプリのようなアプリは、しばしば他の種類のルックアップをしなければならないと想像することができます。

+0

それはうまくいくかもしれません。私はいくつかの論理を変えなければならないだろうが、プレイヤーよりもむしろ曲の面で考えることは、実際には他の問題の負荷を解決するかもしれない。 – Oli

7
from itertools import groupby 

x = { 
    'bathroom': 'a', 
    'bedroom1': 'a', 
    'kitchen': 'b' 
} 


{ 
    ','.join(i[0] for i in v): k 
    for k,v in groupby(sorted(x.iteritems(), key=lambda p: p[1]), lambda p: p[1]) 
} 
+3

これは、(キー、値)のペアのリストを値でソートする中間ステップが必要です。そうでなければ、同じ値が繰り返しで一緒になることは保証されません。 –

+0

@DavidZあなたは正しいです。 – Andrey

関連する問題