排列数字列表,允许联系

Red*_*rty 0 python list

可以说我有一个这样的列表:

newIndexVertList = [0, 1, 2, 2, 1, 20, 21, 21, 20, 3, 23, 22]
Run Code Online (Sandbox Code Playgroud)

我想将其转换为:

newIndexVertList = [0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6]
Run Code Online (Sandbox Code Playgroud)

这里,变换基于原始列表中按升序排列的数字位置.因此,在新的列表中,数字会根据逻辑被替换:

0   -->  0    0th position in sorted list
1   -->  1    1st position in sorted list
2   -->  2    2nd position in sorted list
3   -->  3    3rd position in sorted list
20  -->  4    4th position in sorted list
21  -->  5    5th position in sorted list
22  -->  6    6th position in sorted list
23  -->  7    7th position in sorted list
Run Code Online (Sandbox Code Playgroud)

以下是我的代码:

c = 0
for i in xrange(len(newIndexVertList)):
    if c < newIndexVertList[i]:
        newIndexVertList[i] = c
        c += 1
        continue
    elif c == newIndexVertList[i]:
        c += 1
        continue
    else:
        continue

# actual output:   [0, 1, 2, 2, 1, 3, 4, 5, 6, 3, 7, 8]
# expected output: [0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6]
Run Code Online (Sandbox Code Playgroud)

我的代码有什么问题?实现这一目标的优雅方式是什么?

由于我的顶点列表将在100k范围内,我正在寻找最快的执行.

Moi*_*dri 7

您可以通过创建中间dict对象来实现它,通过使用sorted()set()使用enumerate()以下内容将数字与其在原始列表中的位置进行映射:

>>> my_list = [0, 1, 2, 2, 1, 20, 21, 21, 20, 3, 23, 22]
>>> num_map  = {j: i for i, j in enumerate(sorted(set(my_list)))}
#                                             ^    ^ to get unique elements
#                                             ^ sort numbers in ascending order

>>> [num_map[n] for n in my_list]
[0, 1, 2, 2, 1, 4, 5, 5, 4, 3, 7, 6]
Run Code Online (Sandbox Code Playgroud)

正如Stefan评论的那样,它可以通过单行实现map():

list(map({j: i for i, j in enumerate(sorted(set(my_list)))}.get, my_list))
# ^ type-cast `map` object to `list` for Python 3.x compatibility
Run Code Online (Sandbox Code Playgroud)