0

I am new to Python and I am trying to understand why we use the square brackets inside the len() function:

def counts(txt):
    return len([letter for letter in txt.lower() if letter in "aeiou"])

If I remove the square brackets, I get

TypeError: object of type 'generator' has no len()

but I don't understand what that means.

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • 2
    See [list comprehensions](https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions). – 9769953 Jan 27 '22 at 10:48
  • It's because you invoke the *lower()* function as part of the list comprehension – DarkKnight Jan 27 '22 at 10:53
  • 1
    @JCaesar That has nothing to do with using `lower` or not. – mkrieger1 Jan 27 '22 at 10:56
  • 1
    This could really be written as `sum(letter in 'aeiou' for letter in txt.lower())`… – deceze Jan 27 '22 at 10:57
  • See [How to len(generator())](https://stackoverflow.com/questions/7460836/how-to-lengenerator) and related questions. – mkrieger1 Jan 27 '22 at 11:01
  • Does this answer your question? [What do \[\] brackets in a for loop in python mean?](https://stackoverflow.com/questions/30670310/what-do-brackets-in-a-for-loop-in-python-mean) – Tomerikoo Jan 27 '22 at 11:11

4 Answers4

2

The len function returns the length of a sequence or a collection. So you must pass a sequence or a collection in to this function.

What is causing the confusion is that in this piece of code the programmer created the list in len function itself and passed it as an argument.

Basically [ ] are symbols for lists:

my_list = [letter for letter in txt.lower() if letter in "aeiou"]
return len(my_list)

This is the more readable equivalent of the code you provided.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
0

The same code without comprehension to better understanding. It's really not optimal and not pythonic but it should help you:

def counts(txt):
    data = []                    #     [                                                     ]
    for letter in txt.lower():   #             for letter in txt.lower()
        if letter in "aeiou":    #                                       if letter in "aeiou"
            data.append(letter)  #      letter
    return len(data)             # len(                                                       )
print(counts('hello'))

# Output
2
Corralien
  • 109,409
  • 8
  • 28
  • 52
0

It is simply because the len() function accepts only collections or objects that are iterable.

Some examples:

some examples

Don't get confused with string containing a single letter. It will still return 1 cause it is an object of String class which is iterable.

If you try to pass any object which is not iterable it will throw a

TypeError: object of type 'object_type' has no len()

TypeError

buddemat
  • 4,552
  • 14
  • 29
  • 49
  • Welcome to SO. Please do not add images of code, error messages or data. Instead, write the contents directly into your post and use [markdown to format](https://stackoverflow.com/editing-help) it appropriately. – buddemat Jan 27 '22 at 15:04
-1

The expression inside [] creates a generator. Simply put, a generator is an object, that generates values based on its definition. The only thing it knows is how to create the next value and if it needs to stop. Because of this you first have to exhaust all the values in generator and store them somewhere, which is a list in this case. List has a specified number of items inside it, and thus you can determine its length, unlike a generator.

Similar result could be achieved by counting the letters, that satisfy the if condition:

def counts(txt):
    count = 0
    for letter in txt.lower():
        if letter in "aeiou":
           count += 1
    return count

More on generators: Understanding generators in Python

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
Tzane
  • 2,752
  • 1
  • 10
  • 21
  • square brackets `[...]` are a list comprehension, not a generator – Anentropic Jan 27 '22 at 15:02
  • @Anentropic Yes, but the code in between the square brackets creates a generator object, which is then "unpacked" into a list. – Tzane Jan 27 '22 at 15:10
  • 1
    that's one way to think of it, but the python docs don't describe it that way https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions and the distinction between list comp and generators is already confusing for newcomers – Anentropic Jan 27 '22 at 15:49
  • @Anentropic I can see your point. I was just trying to (unsuccessfully) explain why you couldn't just call `len` on the expression itself, i.e. why you have to "use the square brackets inside". Do you happen to have a source on a better explanation on this? – Tzane Jan 27 '22 at 16:12