2

完全にランダムな要素を持つ多次元配列があります。例えば、

[
    [ [1, 2], [2, 1], [3, 1], [4, 2] ],
    [ [2, 1], [4, 3], [3, 4], [1, 3] ]
]

この配列がはるかに大きいときに後で認識できるように、一意の各要素([1,2]のように、それらの要素ではなく)にIDを割り当てたいのですが、わかりませんそれを出します。私はしばらくインターネットを検索していましたが、運が悪かったので、誰かが正しい方向に私を押してくれたら、本当に感謝しています.

4

4 に答える 4

2

こんな使い方はいかがでしょうか?

class ItemUniqifier(object):
    def __init__(self):
        self.id = 0
        self.element_map = {}
        self.reverse_map = {}

    def getIdFor(self, obj):
        obj_id = self.element_map.get(obj)
        if obj_id is None:
            obj_id = self.id
            self.element_map[obj] = obj_id
            self.reverse_map[obj_id] = obj
            self.id += 1
        return obj_id

    def getObj(self, id):
        return self.reverse_map.get(id)

uniqifier = ItemUniqifier()
print uniqifier.getIdFor((1,2))
print uniqifier.getIdFor((1,2))
print uniqifier.getIdFor("hello")
print uniqifier.getObj(0)
print uniqifier.getObj(1)

これは以下を出力します:

0
0
1
(1, 2)
hello

たとえば、大きな配列を作成するには、次のようにします。

uniqifier = ItemUniqifier()
sample_array = []
for j in range(3):
    inside_array = []
    for i in range(10):
        inside_array.append(uniqifier.getIdFor((i, i+1)))
    sample_array.append(inside_array)

import pprint
pprint.pprint(sample_array)

for inside in sample_array:
    for elem in inside:
        print uniqifier.getObj(elem),
    print

これは以下を出力します:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 10)
(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 10)
(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) (5, 6) (6, 7) (7, 8) (8, 9) (9, 10)
于 2011-12-13T00:07:52.083 に答える
0

各「要素」が2つの1桁の基数10の整数のシーケンスである場合、次のようにその内容からそれぞれに一意のIDを生成できます。

def uniqueID(elem):
    return elem[0]*10 + elem[1]

基本的な考え方は、要素の内容を使用してIDを生成する方法を見つけることです。もちろん、正確にどのように行われるかは、そのコンテンツが何であるかによって異なります。

于 2011-12-13T02:02:09.720 に答える
0

これは、混合型 (リスト、タプル、および文字列) の可変長 (長さがゼロの場合もある) シーケンスを処理できる別の回答です。

class EOS(object): pass  # end-of-sequence marker
EOS = EOS()  # singleton instance

class SeqID(object):
    """ Create or find a unique ID number for a given sequence. """

    class TreeNode(dict):
        """ Branch or leaf node of tree """
        def __missing__(self, key):
            ret = self[key] = self.__class__()
            return ret

    def __init__(self, first_ID=1):
        self._next_ID = first_ID
        self._root = self.__class__.TreeNode()

    def __getitem__(self, seq):
        # search tree for a leaf node corresponding
        # to given sequence and creates one if not found
        node = self._root
        for term in seq:
            node = node[term]
        if EOS not in node:  # first time seq encountered?
            node[EOS] = self._next_ID
            self._next_ID += 1
        return node[EOS]


elements = [
    [ [1, 2], [1, 3], [2, 1], [3, 1], [4, 2] ],
    [ [], [2, 1], [4, 3], [3, 4], (1, 3) ],
    [ [2, 2], [9, 5, 7], [1, 2], [2, 1, 6] ],
    [ 'ABC', [2, 1], [3, 4], [2, 3], [9, 5, 7] ]
]

IDs = SeqID(1000)
print '['
for row in elements:
    print '  [ ',
    for seq in row:
        print '%r: %s,' % (seq, IDs[seq]),
    print ' ],'
print ']'

テストケースに示されている多次元配列の要素を使用すると、例に似ていますが、いくつか追加されているため、次の出力が生成されます。生成された ID 番号1000は、出力で見つけやすくするために強制的に開始されていることに注意してください。

[
  [  [1, 2]: 1000, [1, 3]: 1001, [2, 1]: 1002, [3, 1]: 1003, [4, 2]: 1004,  ],
  [  []: 1005, [2, 1]: 1002, [4, 3]: 1006, [3, 4]: 1007, [1, 3]: 1001,  ],
  [  [2, 2]: 1008, [9, 5, 7]: 1009, [1, 2]: 1000, [2, 1, 6]: 1010,  ],
  [  'ABC': 1011, [2, 1]: 1002, [3, 4]: 1007, [2, 3]: 1012, [9, 5, 7]: 1009,  ],
]

このコードは、各シーケンス内の要素が発生する順序とその内容に基づいて、複数分岐の検索ツリーを内部的に構築することによって機能します。

潜在的な注意点は、生成される ID は、各一意のシーケンスが最初に表示された順序に依存することです。これは、新しい ID はそれぞれ最後の ID よりも 1 つだけ大きいためです。

また、示されているコードではシーケンスのタイプが無視されているため、異なるコンテナーに保持されている同じ要素のシーケンスは同じ ID を生成することに注意してください。ただし、タイプを考慮して変更することもできます。

于 2011-12-29T23:49:31.723 に答える
0

最も簡単な方法は、次のように辞書を使用することです。

id_map = { 'some_id'  : example_array[0][0][0], # maps 'some_id'  to [1, 2]
           'other_id' : example_array[0][1][3], # maps 'other_id' to [3, 4]
           # add more if wanted...
         }

辞書はアルファベットキーと数字キーの両方を使用できますが、インデックスを参照するために数字キーを使用することはお勧めしません。リスト インデックスの番号付けと混同する可能性があるためです。

さらに、辞書は次のようにオンデマンドで新しいキーを追加できます。

id_map[new_key] = new_pair

リストが動的に生成されたと言ったので、これが最良の選択です。

各数値ペアは 3 つのインデックス呼び出しでアクセスされるため、ID を 3 桁にする必要があるでしょうか? たとえば、 idおよびid[1, 2]にマップします。'000'[3, 4]'013'

辞書 - Python ドキュメント

于 2011-12-12T23:08:30.047 に答える