Как добавить количество для каждого уникального значения в списке
Предположим, у меня есть список.
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)]
Ответы
Ответ 1
Вы можете использовать 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']
Ответ 2
Вы можете использовать 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']
Обратите внимание, что seen.update(c)
может привести к неожиданным результатам, если вы ожидаете строки с более чем одним символом в temp
. Демонстрация:
>>> 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']
Ответ 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']
Ответ 4
На самом деле возможно (как ОП попросил в некоторых комментариях) сделать это с помощью простого понимания списка, без слишком большого количества нежелательных побочных эффектов. Однако я не уверен, что это хорошая идея - некоторые люди могут не найти этот код проще всего для понимания:
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]