-2

I am learning python and in the course, I had to make a translator that transforms vowels into the letter "g". In the program, I had to check if the phrase to be translated had any uppercase vowels in order to replace them with a capital letter "G". And I fail to understand why .lower() doesn't apply for the rest of the code? In my thinking, if I apply letter.lower() in the next line the value of the variable letter should still be in lowercase. Here is my code:

def translate(phrase):
translated = ""
for letter in phrase:
    if letter.lower() in "aeouiy":
        if letter.isupper():
            translated = translated + "G"
        else:
            translated = translated + "g"
    else:
        translated = translated + letter
return translated
print(translate(input("enter phrase to translate into giraffe elegant language: ")))
Mehdi RH
  • 322
  • 1
  • 7
  • 18
  • 3
    *"the value of the variable letter should still be in lowercase"* - that's not true at all. Strings are *immutable*, `.lower()` gives you a *new string object*. – jonrsharpe Apr 06 '20 at 10:53
  • 1
    No, `some_string.lower()` creates a new `str` object. It doesn't modify the object in-place. Don't thinkin terms of "modifying variables". That is what assignment is for. When you call a method, you either mutate an object or you don't mutate an object. – juanpa.arrivillaga Apr 06 '20 at 10:53
  • 1
    If you encounter questions like this it would be prudent to research the functiones behaviour in its _documentation_ like ... [str.upper()](https://docs.python.org/3/library/stdtypes.html#str.lower) – Patrick Artner Apr 06 '20 at 10:54
  • And where is that new string object is stored if not in ```letter```? – Mehdi RH Apr 06 '20 at 10:55
  • 1
    @MehdiRezzagHebla it isn't stored anywhere. You don't assign the result of `letter.lower()` to anything. It is unreachable and eligible for garbage collection. In CPython, which uses reference counting as it's memory management strategy, it will be reclaimed immediately when it's reference count reaches zero, which is after the `if` clause completes. – juanpa.arrivillaga Apr 06 '20 at 10:56
  • 1
    it is created, used and destroyed because you do not assign it to a variable – Patrick Artner Apr 06 '20 at 10:56

4 Answers4

5

The strings in Python are immutable.

Strings are immutable sequences of Unicode code points.

And the lower() method of str class in Python doesn't modify the object in-place but it returns a new str object with all of it's characters lower cased.

Lower():

Return a copy of the string with all the cased characters converted to lowercase. For 8-bit strings, this method is locale-dependent.

See this too:

The lowercasing algorithm used is described in section 3.13 of the Unicode Standard.

You will need to reassign your str object to the one returned by lower() method. Like this:

letter = letter.lower()
Community
  • 1
  • 1
abhiarora
  • 9,743
  • 5
  • 32
  • 57
1

.lower() is only applied for the line you are using it in. If you want to have it permanently, you have to assign it like this:

letter = letter.lower()
Carsten
  • 2,765
  • 1
  • 13
  • 28
1

letter.lower() only applies for that line. You would need to change letter itself with letter = letter.lower().

Chris
  • 4,009
  • 3
  • 21
  • 52
1

No, letter.lower() returns a new, lower-cased letter. (In Python, strings are immutable.)

You'll need to reassign back to the name letter to get the behavior you want:

for letter in phrase:
    letter = letter.lower()
    if letter in "aeouiy":
    ...

or better yet, just lower-case all of phrase first:

phrase = phrase.lower()
for letter in phrase:
   ...
AKX
  • 152,115
  • 15
  • 115
  • 172