Given a string, return n distinct characters with their respective counts, as well as the remainder of the string Going through some old code, I found this function.

Given a string carrier and integer nsyms, it consumes nsyms distinct characters from the carrier string and returns a dictionary containing consumed characters and their respective counts, and the remainder of the carrier string.

def enc_consume(carrier, nsyms):
  chrs = defaultdict(int)

  i = 0  # see this?

  for i,c in enumerate(carrier):
    # `i` is not used in the loop
    chrs[c] += 1
    if len(chrs) == nsyms:
      break

  return chrs, carrier[i+1:]  # but it's used here


How would you rewrite this? I found the assignment i = 0 confusing, since it was followed by a for i..., which will of course do the assignment as well.



EDIT: The point of the explicit assignment i = 0 is that if carrier is empty, the loop will not execute. If it weren't for the assignment, i would be undefined by the time it is used in return.
I would avoid using indexes altogether and rely on iter to advance character by character and remember what's left in the string:

def enc_consume(carrier, nsyms):
    characters = defaultdict(int)
    stream = iter(carrier)

    for char in stream:
        characters[char] += 1
        if len(characters) &gt;= nsyms:
             break

    return characters, ''.join(stream)