Python:将一个字符串'keys'列表为int

Gre*_*ers 4 python string int enumerate

我搜索了一会儿,但没有找到任何解释我正在尝试做什么的东西.

基本上我有一个字符串"标签"列表,例如["棕色","黑色","蓝色","棕色","棕色","黑色"]等.我想要做的是将其转换为列表每个标签对应一个整数的整数,所以

["brown", "black", "blue", "brown", "brown", "black"]
Run Code Online (Sandbox Code Playgroud)

[1, 2, 3, 1, 1, 2]
Run Code Online (Sandbox Code Playgroud)

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

[(1,"brown"),(2,"black"),(3,"blue"),(4,"brown"),(5,"brown"),(6,"black")]
Run Code Online (Sandbox Code Playgroud)

我知道如何用一个冗长而繁琐的for循环和if-else检查来做到这一点,但我真的很好奇,如果只有一两行就有更优雅的方式来做这件事.

Mar*_*ers 7

你有非独特的标签; 您可以使用a 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]
Run Code Online (Sandbox Code Playgroud)

这将按照首次出现的标签的顺序生成计数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')]
Run Code Online (Sandbox Code Playgroud)

因为我们使用的是字典,所以标签到数字的查找是固定成本的,因此整个操作将根据labels列表的长度采用线性时间.

或者,使用a set()获取唯一值,然后将这些值映射到enumerate()计数:

label_to_number = {label: i for i, label in enumerate(set(labels), 1)}
[(label_to_number[label], label) for label in labels]
Run Code Online (Sandbox Code Playgroud)

这更加任意地分配数字,因为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')]
Run Code Online (Sandbox Code Playgroud)

这需要循环labels两次.

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