2

これが明らかな場合は申し訳ありませんが、私は Python に非常に慣れていません。辞書から複数のキーを取得する方法を見つけましたが、それは私がやろうとしていることではありません。

基本的に私はこのようなものを探しています:

my_dict = { "1-10" : "foo",
            "11-20" : "bar",
            # ...
            "91-100" : "baz" }

...しかし、キーは実際には文字列ではなく、その指定された範囲内の任意の数値が値にマップされます。したがって、たとえば、すべきと同じように、my_dict[9]を返す必要があります。次のような明示的な配列を使用することを考えましたが、うまくいきませんでした。foomy_dict[3]

my_dict = { [1, 2, 3, ..., 10] : "foo",

これが辞書の有効なユースケースであるかどうか、または使用すべき別のデータ構造があるかどうかはわかりません。しかし、Python には常に私を驚かせる方法があります。それで、これを機能させるためのPythonの魔法を知っている人はいますか?

4

6 に答える 6

3

このようなことをする必要はまったくなかったと言わざるを得ず、そのための組み込みのデータ構造は確かにありません。(ハッシュについて少しでも知っていれば、dict がそのように機能しない理由を理解できるでしょう。)

1 つの可能性は、dict をまったく使用せず、キーと値の個別のリストを持ち、キー リストを各「範囲」の先頭にすることです。そう:

keys = [0, 10, 20, 30]
values = ['foo', 'bar', 'baz', 'quux']

bisectこれで、関連するキーを見つけるために使用できます。

import bisect
pos = bisect.bisect_left(keys, 12)
value = values[pos-1]
于 2013-08-28T14:50:04.773 に答える
2

これは確かに一般的なケースではありません。明らかな解決策を使用することをお勧めします。

my_dict = dict((i, "foo") for i in range(1,10))
print my_dict
{1: 'foo', 2: 'foo', 3: 'foo', 4: 'foo', 5: 'foo', 6: 'foo', 7: 'foo', 8: 'foo', 9: 'foo'}

新しい要素を追加するには、次のように辞書を更新できます。

my_dict.update(new_elements) 
于 2013-08-28T14:47:08.920 に答える
1

「範囲キー」が有効な可能性のあるすべてのキーに対して一意のマッピングを使用した単純な数学的変換である場合は、サブクラス化して and をオーバーライドできますが、list呼び出しコードでヘルパー メソッドまたは直接計算を使用するだけの十分な理由があります (特に何かを返すなど)。意味あり)。__getitem____setitem__index()

class RangeList(list):
    def __getitem__(self, index):
        return super(RangeList, self).__getitem__(index / 10 if index else 0)
    def __setitem__(self, index, value):
        super(RangeList, self).__setitem__(index / 10 if index else 0, value)
于 2013-08-28T14:49:21.283 に答える
0

あなたはこれに沿って何かをすることができます:

class my_dict(dict):
    def __getitem__(self, a):
        return dict.__getitem__(self, (a-1) / 10)
    def __setitem__(self, a, b):
        dict.__setitem__(self, (a-1) / 10, b)

dict_instance = my_dict()
dict_instance[1] = 'foo'
print dict_instance[9] # prints foo

dict_instance[17] = 'bar'
print dict_instance[12] # prints bar

これには、通常の dict (O(1)) と同じくらい高速であるという利点がありますが、10 分の 1 です。

また、範囲を出力したい場合は __ str__ を上書きする必要があります。このデータ型を使用すると、一意のキーを非常に簡単にループすることもできます:)

于 2013-08-28T15:04:19.083 に答える
0

私はこれを記録に残し、他の人が興味を持っているかもしれません:

キーのタプルを作成すると機能します: my_dict = {(1, 2, 3, 10): "foo"}

編集:キーとしてリストが必要だと思いました。それ以外の場合は、次のようにする必要があります。

>>> import numpy as np
>>> keys = np.arange(10,dtype=int)
>>> values = np.arange(3,13)
>>> d = dict(numpy.array([keys,values]).T)
>>> d
{0: 3, 1: 4, 2: 5, 3: 6, 4: 7, 5: 8, 6: 9, 7: 10, 8: 11, 9: 12}
于 2013-08-28T14:48:51.520 に答える