为列表中的每个唯一值分配一个数字

新手上路,请多包涵

我有一个字符串列表。我想为每个字符串分配一个唯一的数字(确切的数字并不重要),并使用这些数字按顺序创建一个相同长度的列表。以下是我最好的尝试,但我不满意有两个原因:

  1. 它假定相同的值彼此相邻

  2. 我必须以 0 开始列表,否则输出将不正确

我的代码:

 names = ['ll', 'll', 'll', 'hl', 'hl', 'hl', 'LL', 'LL', 'LL', 'HL', 'HL', 'HL']
numbers = [0]
num = 0
for item in range(len(names)):
    if item == len(names) - 1:
      break
    elif names[item] == names[item+1]:
        numbers.append(num)
    else:
        num = num + 1
        numbers.append(num)
print(numbers)

我想让代码更通用,这样它就可以处理未知列表。有任何想法吗?

原文由 millsy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 316
2 个回答

如果不使用外部库(检查 EDIT 中的 Pandas 解决方案),您可以按如下方式进行:

 d = {ni: indi for indi, ni in enumerate(set(names))}
numbers = [d[ni] for ni in names]

简要说明:

在第一行中,您为列表中的每个唯一元素分配一个数字(存储在字典中 d ;您可以使用字典理解轻松创建它; set 返回唯一元素 names )。

然后,在第二行中,您进行列表理解并将实际数字存储在列表中 numbers

一个例子来说明它也适用于未排序的列表:

 # 'll' appears all over the place
names = ['ll', 'll', 'hl', 'hl', 'hl', 'LL', 'LL', 'll', 'LL', 'HL', 'HL', 'HL', 'll']

这是 numbers 的输出:

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

如您所见,与 1 ll 出现在正确的位置。

编辑

如果你有 Pandas 可用,你也可以使用 pandas.factorize (这对于大列表来说似乎非常有效,并且对于元组列表也可以正常工作,如此 所述):

 import pandas as pd

pd.factorize(names)

然后会返回

(array([(array([0, 0, 1, 1, 1, 2, 2, 0, 2, 3, 3, 3, 0]),
 array(['ll', 'hl', 'LL', 'HL'], dtype=object))

所以,

 numbers = pd.factorize(names)[0]

原文由 Cleb 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果条件是数字是唯一 _的并且确切的数字并不重要_,那么您可以构建一个映射,将列表中的每个项目动态地关联到一个唯一的数字,从计数对象中分配值:

 from itertools import count

names = ['ll', 'll', 'hl', 'hl', 'LL', 'LL', 'LL', 'HL', 'll']

d = {}
c = count()
numbers = [d.setdefault(i, next(c)) for i in names]
print(numbers)
# [0, 0, 2, 2, 4, 4, 4, 7, 0]


您可以通过在列表和计数对象上使用 map 并将映射函数设置为 {}.setdefault 来消除额外的名称(参见@StefanPochmann 的评论):

 from itertools import count

names = ['ll', 'll', 'hl', 'hl', 'LL', 'LL', 'LL', 'HL', 'll']
numbers  = map({}.setdefault, names, count()) # call list() on map for Py3
print(numbers)
# [0, 0, 2, 2, 4, 4, 4, 7, 0]


另外,您还可以使用 np.unique ,以防您已经安装了 numpy:

 import numpy as np

_, numbers = np.unique(names, return_inverse=True)
print(numbers)
# [3 3 2 2 1 1 1 0 3]

原文由 Moses Koledoye 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题