0

I have the following input:

'lesson*lesson*practice*lesson*quiz*practice'

and here's the desired output:

'lesson1*lesson2*practice1*lesson3*quiz*practice2'

So if any item repeats in the list, I'd like to append 1,2,3... to the occurrences. To get this done, I came up with the following code:

line = 'lesson*lesson*practice*lesson*quiz*practice'
line1 = line

def list_to_dict(li):  
    dct = {}  
    for item in li.split('*'):  
        if dct.has_key(item):  
            dct[item] = dct[item] + 1  
        else:  
            dct[item] = 1  
    return dct

for item in list_to_dict(line).keys():
    counter = 1
    if list_to_dict(line)[item] > 1:
        indices = [i for i, x in enumerate(line.split('*')) if x == item]
        for idx, _ in enumerate(line1[indices]):
            line1[idx] = line1[idx] + str(counter)
            counter = counter + 1

print line1
print line

But this code gives me the following error:

TypeError                                 Traceback (most recent call last)
<ipython-input-187-a85290a89eea> in <module>()
      6     if list_to_dict(line)[item] > 1:
      7         indices = [i for i, x in enumerate(line) if x == item]
----> 8         for idx, _ in enumerate(line1[indices]):
      9             line1[idx] = line1[idx] + str(counter)
     10             counter = counter + 1

TypeError: string indices must be integers, not list

Would someone please be able to help get the desired output?

If you think my algorithm to achieve this is not good, I'd welcome any new ideas, too.

Patthebug
  • 4,647
  • 11
  • 50
  • 91
  • What is `for idx, _ in enumerate(line1[indices]):` supposed to do? –  Nov 03 '16 at 17:53
  • Shouldn't it just be `for idx in indices:` – Patrick Haugh Nov 03 '16 at 17:54
  • @LutzHorn: I took the particular piece of code you're tlaking about, from http://stackoverflow.com/questions/3173915/modification-of-the-list-items-in-the-loop-python . This is to replace items within a list. – Patthebug Nov 03 '16 at 17:59
  • @PatrickHaugh: I tried what you're saying earlier, and I get the following error: `TypeError Traceback (most recent call last) in () 7 indices = [i for i, x in enumerate(line.split('*')) if x == item] 8 for idx in indices: ----> 9 line1[idx] = line1[idx] + str(counter) 10 counter = counter + 1 11 TypeError: 'str' object does not support item assignment` – Patthebug Nov 03 '16 at 18:00
  • So you've copied code you do not understand and ask us to explain it to you? –  Nov 03 '16 at 18:05

2 Answers2

2

I didn't try your code but I suspect using a dict will cause ordering problems? Here's a solution:

from collections import Counter

def add_counts_to_words(s):
    words = s.split('*')
    totals = Counter(words)
    counts = Counter()
    result = []
    for word in words:
        if totals[word] > 1:
            counts.update([word])
            result.append('%s%d' % (word, counts[word]))
        else: # singleton
            result.append(word)
    return '*'.join(result)

print add_counts_to_words('lesson*lesson*practice*lesson*quiz*practice')
James Fryer
  • 229
  • 1
  • 3
0

Not sure why you are trying to reinvent collections.Counter

But you over overcomplicate your answer

from collections import Counter

line = 'lesson*lesson*practice*lesson*quiz*practice'
line_list = line.split('*')

counter = Counter()
output_list = []
for elem in line_list:
    counter.update((elem, 1))
    output_list.append(''.join((elem, str(counter[elem]))))

'*'.join(output_list)

Output:

'lesson1*lesson2*practice1*lesson3*quiz1*practice2'
vishes_shell
  • 22,409
  • 6
  • 71
  • 81