如何为列表中的每个唯一值添加计数
How to add count for each unique val in list
假设我有一个列表。
temp = ['A', 'B', 'A', 'B', 'A', 'B']
我正在寻找一种方法来加入字符串的计数。
预期输出:
['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
我能够通过使用列表推导来解决它,但我正在寻找一种无需指定列表的方法 [1, 1, 2, 2, 3, 3]
。可能吗?
[j + "_" + str(i) for i, j in zip([1, 1, 2, 2, 3, 3], temp)]
您可以将 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']
您可以使用字典(或者更好的是 collections.defaultdict
)来维护每个项目的计数:
from collections import defaultdict
lst = ['A', 'B', 'A', 'B', 'A', 'B']
lst2 = []
d = defaultdict(int)
for item in lst:
d[item] += 1
lst2.append('{}_{}'.format(item, d[item]))
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
要在此处使用列表理解,您需要一些方法来在迭代原始列表时更新每个项目的状态(即计数器)。为此,您可以使用带有默认参数的函数,例如:
def get_count(item, d=defaultdict(int)):
d[item] += 1
return '{}_{}'.format(item, d[item])
lst2 = [get_count(item) for item in lst]
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
您可以使用 Counter
或 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']
请注意,如果您希望字符串在 temp
中包含多个字符,则 seen.update(c)
可能会产生意想不到的结果。演示:
>>> seen = Counter()
>>> seen.update('ABC')
>>> seen
>>> Counter({'A': 1, 'B': 1, 'C': 1})
根据您希望的计数方式和期望的数据类型,您可能希望使用行
seen[c] += 1
而不是
seen.update(c)
或者,没有任何导入:
>>> 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']
事实上(正如 OP 在一些评论中所要求的那样)仅通过列表理解就可以做到这一点,而没有太多不良副作用。我不确定这是否一定是个好主意 - 有些人可能觉得它不是最容易理解的代码:
from collections import defaultdict
import itertools
temp = ['A', 'B', 'A', 'B', 'A', 'B']
result = [j + "_" + str(next(c[j]))
for c in [defaultdict(itertools.count)]
for j in temp]
假设我有一个列表。
temp = ['A', 'B', 'A', 'B', 'A', 'B']
我正在寻找一种方法来加入字符串的计数。
预期输出:
['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
我能够通过使用列表推导来解决它,但我正在寻找一种无需指定列表的方法 [1, 1, 2, 2, 3, 3]
。可能吗?
[j + "_" + str(i) for i, j in zip([1, 1, 2, 2, 3, 3], temp)]
您可以将 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']
您可以使用字典(或者更好的是 collections.defaultdict
)来维护每个项目的计数:
from collections import defaultdict
lst = ['A', 'B', 'A', 'B', 'A', 'B']
lst2 = []
d = defaultdict(int)
for item in lst:
d[item] += 1
lst2.append('{}_{}'.format(item, d[item]))
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
要在此处使用列表理解,您需要一些方法来在迭代原始列表时更新每个项目的状态(即计数器)。为此,您可以使用带有默认参数的函数,例如:
def get_count(item, d=defaultdict(int)):
d[item] += 1
return '{}_{}'.format(item, d[item])
lst2 = [get_count(item) for item in lst]
print(lst2) # ['A_1', 'B_1', 'A_2', 'B_2', 'A_3', 'B_3']
您可以使用 Counter
或 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']
请注意,如果您希望字符串在 temp
中包含多个字符,则 seen.update(c)
可能会产生意想不到的结果。演示:
>>> seen = Counter()
>>> seen.update('ABC')
>>> seen
>>> Counter({'A': 1, 'B': 1, 'C': 1})
根据您希望的计数方式和期望的数据类型,您可能希望使用行
seen[c] += 1
而不是
seen.update(c)
或者,没有任何导入:
>>> 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']
事实上(正如 OP 在一些评论中所要求的那样)仅通过列表理解就可以做到这一点,而没有太多不良副作用。我不确定这是否一定是个好主意 - 有些人可能觉得它不是最容易理解的代码:
from collections import defaultdict
import itertools
temp = ['A', 'B', 'A', 'B', 'A', 'B']
result = [j + "_" + str(next(c[j]))
for c in [defaultdict(itertools.count)]
for j in temp]