【问题标题】:Python: Enumerate a list of string 'keys' into intsPython:将字符串“键”列表枚举为整数
【发布时间】:2013-06-13 16:46:35
【问题描述】:

我搜索了一段时间,但没有找到任何可以准确解释我想要做什么的东西。

基本上我有一个字符串“标签”列表,例如["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 检查来完成此操作,但我真的很好奇是否有更优雅的方法可以仅用一两行代码完成此操作。

【问题讨论】:

    标签: python string int enumerate


    【解决方案1】:

    您有非唯一标签;您可以使用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

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 如果标签列表很大,这将非常糟糕,因为.index() 必须为每个循环迭代扫描列表。
      • 这就是我所说的,当我说长列表可能会变慢时,它会深入了解列表的大小。
      • 这也假设了关于整数赋值的问题中没有明确的内容。第二个示例(例如l = ["brown", "black", "brown", "blue", "brown", "black"])会为“蓝色”分配 4,而字典方法在这两种情况下都会为“蓝色”分配 3。
      【解决方案3】:

      试试这个:

      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 等。

      【讨论】:

        【解决方案4】:

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

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

        然后:

        li = ["brown", "black", "blue", "brown", "brown", "black"]
        [dict[i] for i in li]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-27
          • 1970-01-01
          • 1970-01-01
          • 2023-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多