2

我有一个多维数组,其中的元素可以完全随机。例如,

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

我想为每个唯一元素分配一个 ID(如 [1,2] 中的元素,而不是其中的元素),以便稍后当这个数组更大时我可以识别它,但我似乎无法弄清楚出来。我已经在互联网上搜索了一段时间,但没有运气,所以如果有人可以推动我朝着正确的方向前进,我将非常感激。

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

最简单的方法是使用字典,如下所示:

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 个索引调用访问的,也许您应该将 ids 设为 3 位长?例如,[1, 2]将映射到 id'000'[3, 4]id '013'

字典 - Python 文档

于 2011-12-12T23:08:30.047 回答
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,因为在显示的代码中忽略了序列的类型——但也可以更改它以考虑类型。

于 2011-12-29T23:49:31.723 回答
0

如果每个“元素”是两个以 10 为基数的单位数的序列,您可以从其内容中为每个元素生成一个唯一的 id,如下所示:

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

基本思想是找出某种方法来使用元素的内容来生成 ID。当然,具体如何完成将取决于内容是什么。

于 2011-12-13T02:02:09.720 回答