2012-02-05 8 views
2

ここでPython初心者は、値が特定の数字になるような方法で2つのリストを辞書に結合する方法があるかどうかを知りたかったのです。ここで私は結合しようとしている3つのデータセットの例です:リストを参照属性としてリストに追加する方法はありますか?

[17, 39, 9] [13, 37, 13] = 0.13517353359 
[17, 39, 9] [15, 38, 10] = 0.055003044449 
[13, 39, 13] [13, 37, 13] = 0.0345037548204 
[13, 39, 13] [15, 38, 10] = 0.0801704891415 
[14, 39, 12] [13, 37, 13] = 0.0596711995129 
[14, 39, 12] [15, 38, 10] = 0.055003044449 
[15, 39, 11] [13, 37, 13] = 0.0848386442054 
[15, 39, 11] [15, 38, 10] = 0.0298355997564 
[16, 39, 10] [13, 37, 13] = 0.110006088898 
[16, 39, 10] [15, 38, 10] = 0.0298355997564 

は、私は本当に数字を並べ替えることができるようにしたい(私はすでにこの作業を行う機能を持っている)し、最初のリストでルックアップしたいです(しかし、第2のリストを参照として必要とする)。

私はname = "%s-%s" % ([16, 39, 10], [15, 38, 10])のようなことを考えていましたが、dictに名前を付け加えましたが(数値は値)、この問題は[16,39,10]で検索できませんでした。 {[16、39、10]:[[15、38、10]、0.0298355997564]}のような辞書を作ることができましたが、その後私の検索機能が壊れます。

私はうんざりなことをしなければならないかもしれないと思うが、これにアプローチするより良い方法があるのだろうかと思っていた。理想的には、私は{[16, 39, 10]:0.0298355997564}のような単純な辞書を必要とし、[15,38,10]は必要なときに参照できる属性です)。

これは可能ですか?

編集:詳細:後で参考にする必要がある場合に備えて(この特定の例では、[16,39,10] 2つ目のリストは結果の間では異なりますが、私の完全なデータセットには重複が多くないので、特定のケースで参照するだけです)。

+0

"が、基準となる第二のリスト必要がある" - あなたは正確に何を意味するのですか? – Wes

+0

後で参照する必要がある場合に備えて、私はそれを必要とします(この特定の例では、[16,39,10]の複製を見つけたときに結果間で2番目のリストを使用しますが、それほど重複していないので、特定の場合に参照するだけです)。 – Lostsoul

+0

私は2番目のリストをリストのリストに入れ、必要なときにだけそれを参照することを考えていましたが、ディクテーションには番号が付いていないので論理を理解できませんでした。(したがって、dictの位置1は位置1リストのリストに) – Lostsoul

答えて

2

リストは、変更可能であるため、辞書キーにすることはできません。データが静的な場合は、タプルに変換してキーとして使用できます。値は、2番目のリストとfloat値のタプルでもあります。

data = { 
     (17, 39, 9): ([13, 37, 13], 0.13517353359), 
     (17, 39, 9): ([15, 38, 10], 0.055003044449), 
     (13, 39, 13): ([13, 37, 13], 0.0345037548204), 
    } 

    print "Other list:", d[(17, 39, 9)][0] 
    print "Float", d[(17, 39, 9)][1] 
+0

ありがとう。あなたのコードを試してみると、それは他のリスト[15,38,10]の結果を返しますが、どのようにして最初のエントリにアクセスできますか? (17,39,9):([13,37,13]、0.13517353359)。最初のエントリが2番目のエントリによって上書きされているようです。 – Lostsoul

+0

私はちょうどデータのxのためにしました:print xそしてそれは2つのエントリーをリストします – Lostsoul

+0

@LostSoul:あなたはお互いをオーバーライドするDUPLICATESを持っているからです。 –

2

ハッシュ可能になるようにリストをタプルにする必要があります。

>>> l = [1,2,3] 
>>> d = { l: 5 } 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 
>>> t = tuple(l) 
>>> d = { t: 5 } 
>>> d[t] 
5 

しかし、あなたの質問を読んで、それは戦いの半分です。また、2番目のリストも取得できるようにする必要があります。

その後
d = { t: (second_list, result) } 

、あなたが結果または第二のリストを必要とする...

other_list, result = d[t] 

あなたは辞書ではなく、単一から取得されたタプルを考慮するために、検索機能を変更する必要があります値。

ちなみに、あなたのデータセットを変更する必要がない場合(あなたの2つのリスト)、とにかくそれらをタプルにすることを検討してください。

+0

それはクールだった!私はこのように使用することを考えなかったし、私もfrozensetsについて知りませんでした。ありがとう!私はあなたのコードに少し問題がありますが、私はデータと2番目のリストにアクセスできますが、最初のリスト(あなたの例では、tの値)にアクセスすることはできません。どのようにして最初のリストにアクセスできますか? – Lostsoul

+0

@LostSoul:あなたが離れている間に、ジョシュは答えを変えました。 frozensetsはUNcoolです。私の答えを見てください。 –

+0

@LostSoul: "最初のリストにアクセスするにはどうすればいいですか" ...最初のリスト(タプルでなければなりません)は、あなたのdictへのKEYです - あなたがすでに知っているはずなので、データ番号と2番目のリスト(タプルでなければなりません)。 –

0

これはスペースが少し浪費されますが、2つの異なるdictがそれぞれ最初の数字の組で参照されます。

{(17,39,10): 0.13517353359, ...} 

{(17,39,10): [13, 37, 13], ... } 

あなたはハッシュ可能であることを主要なニーズので、キーではなく、リストとしてtuple Sを使用する必要があります注意してください。

Ahaですが、異なる番号とリストを持つ重複するキーがあることに気がつきました。だから、普通の古いものを使うことはできません。dict ....あなたはすでに検索機能を持っていると言います。どのようなデータ構造が使用できますか?

2

Iは次のように辞書を作ることができる{[16、39、10]:[15、38、10]、 0.0298355997564]}

いいえができませんでした。 dictキーはハッシュ可能である必要があります。リストはハッシュ可能ではありません。あなたは、リストの代わりにタプルを使用することができます。

タプルとfrozensetの間で選択
>>> x = {[16, 39, 10]:[[15, 38, 10], 0.0298355997564]} 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'list' 
>>> x = {(16, 39, 10):[[15, 38, 10], 0.0298355997564]} 
>>> x 
{(16, 39, 10): [[15, 38, 10], 0.0298355997564]} 

:frozenset型はあまり効率的です。

>>> (16, 39, 10) != (10, 39, 16) 
True # different 
>>> frozenset((16, 39, 10)) != frozenset((10, 39, 16)) 
False # same!! 

が、その後、私の検索機能ブレーク:もっと重要なのは、frozenset型は順序を保持しません。

まあまあ、あなたは検索機能を変更する必要があります。

を更新して、複数の複製を許可します。

データがテーブル(リスト)に格納されているデータベースのようにしましょう。あなたはいつでもフルテーブルスキャンでアクセスできますが、2つのインデックス(defaultdicts)を各外部キーに1つ提供します。

コード:

data = [ 
    ((17, 39, 9), (13, 37, 13), 0.13517353359), 
    ((17, 39, 9), (15, 38, 10), 0.055003044449), 
    ((13, 39, 13), (13, 37, 13), 0.0345037548204), 
    ((13, 39, 13), (15, 38, 10), 0.0801704891415), 
    ((14, 39, 12), (13, 37, 13), 0.0596711995129), 
    ((14, 39, 12), (15, 38, 10), 0.055003044449), 
    ((15, 39, 11), (13, 37, 13), 0.0848386442054), 
    ((15, 39, 11), (15, 38, 10), 0.0298355997564), 
    ((16, 39, 10), (13, 37, 13), 0.110006088898), 
    ((16, 39, 10), (15, 38, 10), 0.0298355997564), 
] 

from collections import defaultdict 
keydict1 = defaultdict(list) 
keydict2 = defaultdict(list) 
for row_index, row in enumerate(data): 
    tup1, tup2, value = row 
    keydict1[tup1].append(row_index) 
    keydict2[tup2].append(row_index) 

def search(keydict, query_tuple): 
    print 
    print "looking for", query_tuple 
    for row_index in keydict[query_tuple]: 
     print row_index, data[row_index] 

search(keydict1, (17, 39, 9)) 
search(keydict2, (13, 37, 13)) 

出力:

looking for (17, 39, 9) 
0 ((17, 39, 9), (13, 37, 13), 0.13517353359) 
1 ((17, 39, 9), (15, 38, 10), 0.055003044449) 

looking for (13, 37, 13) 
0 ((17, 39, 9), (13, 37, 13), 0.13517353359) 
2 ((13, 39, 13), (13, 37, 13), 0.0345037548204) 
4 ((14, 39, 12), (13, 37, 13), 0.0596711995129) 
6 ((15, 39, 11), (13, 37, 13), 0.0848386442054) 
8 ((16, 39, 10), (13, 37, 13), 0.110006088898) 
関連する問題