您有非唯一标签;您可以使用defaultdict 在首次访问时生成数字,并结合计数器:
from collections import defaultdict
from itertools import count
from functools import partial
label_to_number = defaultdict(partial(next, count(1)))
[(label_to_number[label], label) for label in labels]
这会按照标签在labels 中首次出现的顺序生成计数。
演示:
>>> labels = ["brown", "black", "blue", "brown", "brown", "black"]
>>> label_to_number = defaultdict(partial(next, count(1)))
>>> [(label_to_number[label], label) for label in labels]
[(1, 'brown'), (2, 'black'), (3, 'blue'), (1, 'brown'), (1, 'brown'), (2, 'black')]
因为我们使用的是字典,所以标签到数字的查找是固定成本,所以整个操作将根据labels 列表的长度花费线性时间。
或者,使用set() 获取唯一值,然后将它们映射到enumerate() 计数:
label_to_number = {label: i for i, label in enumerate(set(labels), 1)}
[(label_to_number[label], label) for label in labels]
这更随意地分配数字,因为set() 对象没有排序:
>>> label_to_number = {label: i for i, label in enumerate(set(labels), 1)}
>>> [(label_to_number[label], label) for label in labels]
[(2, 'brown'), (3, 'black'), (1, 'blue'), (2, 'brown'), (2, 'brown'), (3, 'black')]
这需要循环两次labels。
这两种方法都不需要您首先定义一个标签字典;映射是自动创建的。