Enumerate explanation

I was trying to find a way to iterate through a string and return a specific character when only unique characters of the string were detected and another character if duplicates were detected (basically encoding the word “cheese” into “(())()”

I started diving into nested loops with counts and sets and trying to figure out how to then produce one character or another depending on which list the iteration was found in, but I came across “enumerate”, which from what I’ve read has the ability to both iterate and return a value, which seems like it fits this scenario.

I am very new to python so many of the terms used to discuss enumerate in other websites just left me more confused and I have found the folks on here extremely helpful with great explanations that were well broken down for the basic beginner. I would appreciate any help you can provide!

1 Like

This is not about enumerate but alternative solution using built-in tool.

Simply put the ‘algorithm’:

  • count all letters in word
  • replace letters which count is 1 to one symbol and all others to another symbol

There is counter in Python conveniently named Counter :slight_smile: . So one can count number of occurrences of letters using Counter, then iterate over letters of word and do replacing and joining the result:

>>> from collections import Counter
>>> word = 'cheese'
>>> count = Counter(word)
>>> ''.join('(' if count[char] == 1 else ')' for char in word)
'(())()'

EDIT:

Regarding built-in enumerate: it provides pythonic way for looping over an iterator/sequence/object which supports iteration and getting the index of each item. Non-pythonic way would be looping over a range and accessing items by index. You can supply a second argument to enumerate to specify the number from which to begin counting (zero is the default).

So instead of this:

>>> word = 'cheese'
>>> for i in range(len(word)):
...     print(f"{i+1}.{word[i]}")
...
1.c
2.h
3.e
4.e
5.s
6.e

Do this:

>>> for i, char in enumerate(word, start=1):
...     print(f"{i}.{char}")
...
1.c
2.h
3.e
4.e
5.s
6.e

So the only thing enumerate “returns” is the position of the elements of whatever it is iterating through? As opposed to returning a specific object. I apologize if I’m messing up the verbiage. So enumerate wouldn’t work for me because it can’t iterate and give me a “(”… only the letter’s position in the string?

What is the space before the .join? Is this an empty string?

When I see this it makes me think I’m counting the elements of a list within the variable name of “char”

It returns consecutive integers along with object itself. You can set start integer by providing argument:

>>> print(*enumerate('cheese', start=42))
(42, 'c') (43, 'h') (44, 'e') (45, 'e') (46, 's') (47, 'e')

If I understood your objective correctly (replace all letters which occur once with one symbol and all others with another) - if you iterate over letters of word and encounter first letter Python don’t know (yet) whether there is same letter in the word. You can keep some sort of track but anyway you have to assign one symbol initially and then, if letter encountered second time you have to change symbol assigned on first occurrence.

Therefore, despite two iterations, it seems to me easier to count words in letter and then make lookup to counter object and provide symbol necessary.

People have different perceptions. For me it’s ‘count character’ :-).

1 Like

enumerate(items) yields a sequence of two values, count, item where item comes from iterating over items.

A concrete example might help:

values = ['ant', 'bee', 'cat', 'dog']
for count, item in enumerate(values):
    print(count, item)

That prints:

0 ant
1 bee
2 cat
3 dog

By default the count starts at zero, but you can pass a starting value to enumerate to start at any other value, e.g. enumerate(values, 100) would start at 100 instead of 0.