如何为列表中的每个唯一val添加计数

Rak*_*esh 16 python string counter list defaultdict

假设我有一个清单.

temp = ['A', 'B', 'A', 'B', 'A', 'B']
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种方法来加入里面的字符串计数.

预期产出:

['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
Run Code Online (Sandbox Code Playgroud)

我能够通过使用列表解析来解决它,但我正在寻找一种方法,我不必指定列表[1, 1, 2, 2, 3, 3].可能吗?

[j + "_" + str(i) for i, j in zip([1, 1, 2, 2, 3, 3], temp)]
Run Code Online (Sandbox Code Playgroud)

jpp*_*jpp 28

您可以使用collections.defaultdict一个for循环:

from collections import defaultdict

L = ['A', 'B', 'A', 'B', 'A', 'B']

dd = defaultdict(int)

res = []
for item in L:
    dd[item] += 1
    res.append(f'{item}_{dd[item]}')

print(res)

['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
Run Code Online (Sandbox Code Playgroud)

  • 你必须在理解中使用布尔表达式,其中对其部分的真实性的评估也调用诸如`__setitem__`之类的方法.相信我,你不需要这里的listcomp. (6认同)
  • @timgeb:实际上你只需要一个列表理解就可以做到这一点,而不会像你提到的那样使用副作用*非常讨厌 - 参见[我的回答](/sf/answers/3717177971/)这样做的一种方式.我仍然不是100%肯定我会建议这样做,但:) (4认同)
  • 在这里同意@timgeb,如果你预先计算了索引值(这将是非常昂贵的),列表理解将起作用.但是当你需要根据*previous*值计算它们时. (2认同)

tim*_*geb 11

您可以使用a Counter或a defaultdict(int)来跟踪角色在遇到角色时被看到的次数.

>>> from collections import Counter
>>> 
>>> temp = ['A', 'B', 'A', 'B', 'A', 'B']
>>> seen = Counter()
>>> 
>>> result = []
>>> for c in temp:
...:    seen.update(c)
...:    result.append('{}_{}'.format(c, seen[c]))
...:    
>>> result
>>> ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
Run Code Online (Sandbox Code Playgroud)

请注意,seen.update(c)如果您希望字符串中包含多个字符,则可能会产生意外结果temp.演示:

>>> seen = Counter()
>>> seen.update('ABC')
>>> seen
>>> Counter({'A': 1, 'B': 1, 'C': 1})
Run Code Online (Sandbox Code Playgroud)

根据您的计算方式以及您期望的数据类型,您可能希望使用该行

seen[c] += 1
Run Code Online (Sandbox Code Playgroud)

代替

seen.update(c)
Run Code Online (Sandbox Code Playgroud)

或者,没有任何进口:

>>> seen = {}
>>> result = []
>>> 
>>> for c in temp:
...:    seen[c] = seen.get(c, 0) + 1
...:    result.append('{}_{}'.format(c, seen[c]))
...:    
>>> result
>>> ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
Run Code Online (Sandbox Code Playgroud)