В исходном вопросе вы, вероятно, (я только что посмотрел на него) использовали set
строк в сложенном регистре, чтобы посмотреть, есть ли у вас новая или повтор, создавая список новых по мере продвижения.
Вы можете заменить это на Counter
вместо set
. Но затем вам нужно построить список, а затем вернуться и отредактировать его с учетом.
Так что вместо этого замените оба set
/ Counter
и список вывода на OrderedDict
, в котором хранятся пары подсчета элементов для каждого сложенного в регистр элемента:
d = collections.OrderedDict()
for item in myList:
caseless = item.lower()
try:
d[caseless][1] += 1
except KeyError:
d[caseless] = [item, 1]
… и затем передайте этот аргумент для создания списка вывода:
myList = []
for item, count in d.values():
if count > 1:
item = '{} ({})'.format(item, count)
myList.append(item)
Вы можете сделать это более кратким (например, myList = ['{} ({})'.format(item, count) if count > 1 else item for item, count in d.values()
), и это также сделает его немного быстрее с небольшим постоянным коэффициентом.
Вероятно, вы можете сбрить несколько наносекунд, используя %
вместо format
и, возможно, даже больше с %d
вместо %s
(хотя я думаю, что последняя часть больше не верна даже на 2,7) .
В зависимости от вашей платформы a[0] += 1
может быть быстрее или медленнее, чем a[1] += 1
. Попробуйте оба способа, и если a[0]
быстрее, используйте [count, item]
пары вместо [item, count]
. Если у вас тонна дупликов, вы можете рассмотреть класс с __slots__
, который на самом деле может быть немного быстрее обновлять, но значительно медленнее создавать, чем список.
Кроме того, использование in
теста или, возможно, сохранение d.__contains__
как локального, может быть быстрее, чем try
- или это может быть медленнее, в зависимости от того, сколько повторений вы ожидаете иметь, поэтому попробуйте все три способа использования фактических данных вместо набора игрушечных данных.