4

我搜索了一段时间,但没有找到任何可以准确解释我正在尝试做的事情。

基本上我有一个字符串“标签”列表,例如 [“brown”、“black”、“blue”、“brown”、“brown”、“black”] 等。我想要做的就是将其转换为列表每个标签对应一个整数的整数,所以

["brown", "black", "blue", "brown", "brown", "black"]

变成

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

我查看了 enumerate 函数,但是当我给它我的字符串列表(很长)时,它为每个单独的标签分配了一个 int,而不是给相同的标签相同的 int:

[(1,"brown"),(2,"black"),(3,"blue"),(4,"brown"),(5,"brown"),(6,"black")]

我知道如何通过冗长而繁琐的 for 循环和 if-else 检查来做到这一点,但我真的很好奇是否有一种更优雅的方法可以只用一两行来做到这一点。

4

4 回答 4

7

你有非唯一的标签;您可以使用 adefaultdict在首次访问时生成数字,并结合计数器:

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列表的长度花费线性时间。

或者,使用 aset()获取唯一值,然后将它们映射到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两次。

这两种方法都不需要您首先定义标签字典;映射是自动创建的。

于 2013-06-17T16:35:37.977 回答
3

您可以首先创建一个字典,如:

dict = {"brown":1 , "black": 2, "blue": 3 }

接着:

li = ["brown", "black", "blue", "brown", "brown", "black"]
[dict[i] for i in li]
于 2013-06-17T16:36:35.223 回答
1

尝试这个:

lst = ["brown", "black", "blue", "brown", "brown", "black"]
d = {"brown":1, "black":2, "blue":3}

[d[k] for k in lst]
=> [1, 2, 3, 1, 1, 2]

当然,要使它起作用,您必须在某处定义等价物-在上面,我使用了字典。否则,无法知道棕色对应数字 1 等。

于 2013-06-17T16:37:05.393 回答
0

重现您请求的答案的最简单的代码是:

l = ["brown", "black", "blue", "brown", "brown", "black"]
i = [l.index(x)+1 for x in l]
print i

>>> [1, 2, 3, 1, 1, 2]

对于很长的列表,这可能会变得很慢,但它会生成您所要求的内容,而无需任何准备。

于 2013-06-17T16:42:57.443 回答