Technically you're using a generator expression, and not a list comprehension. But the result is similar in this case.
You're reading input into s
, but then you're reassigning s
in each iteration, and then you're joining s
.
You need to have a different variable. For the input and for the capitalized list. What a generator expression does is to return one value at a time, instead of building the whole capitalized list at once. But here you will need to declare it.
Also, it doesn't make sense to assign answer in each iteration, the join
is the last thing you need to do, once your capitalized list is prepared.
This should work:
toCapitalize = input('Please enter a string: ')
capitalizedList = []
for idx, char in enumerate(toCapitalize):
if idx % 2:
capitalizedList.append(char.upper())
else:
capitalizedList.append(char.lower())
answer = ''.join(capitalizedList)
print(answer)
In case this helps, I've tried to reflect what line goes with what part of the generator expression below:
for idx, char in enumerate(toCapitalize): # for idx, char in enumerate(s)
if idx % 2: capitalizedList.append(char.upper()) # char.upper() if idx % 2
else: capitalizedList.append(char.lower()) # else char.lower()
answer = ''.join(capitalizedList) # answer = ''.join()
Again, the capitalizedList
variable is implicit in the generator expressions or list comprehensions.
Generator expressions
To understand generator expressions look at this code:
capitalize = 'hello'
generator = (char.upper() if idx % 2 else char.lower() for idx, char in enumerate(capitalize))
print(next(generator)) # h
print(next(generator)) # E
print(next(generator)) # l
print(next(generator)) # L
print(next(generator)) # o
print(next(generator)) # raises a StopIteration exception, we've reached the end.
Each call to next()
calculates the result of the next iteration on the fly. Which is more memory efficient than building a whole list at once when you have big lists. In your case, the call to join()
consumes all the generator, and joins the values returned.
As a list comprehension
Your code as a list comprehension would be:
s = input('Please enter a string: ')
answer = ''.join([ char.upper() if idx % 2 else char.lower() for idx, char in enumerate(s) ])
print(answer)
As I explained above, the difference is that here we're building a whole list at once, the generator is only returning one value at a time.
Your code as a generator
And finally, to be technically correct your code would be equivalent to this:
def generator(s):
for idx, char in enumerate(s):
if idx % 2:
yield char.upper()
else:
yield char.lower()
answer = ''.join(generator(s))
print(answer)
That's how you build a generator in Python.