In Python, anything that is countable by unit is iterable. To find the number of units (elements) in the iterable we are given the built in function, len()
. This is a global function and may be applied to any object that is itself iterable.
What do we mean by, ‘iterable object’? In Python there are a number of defined objects (classes) that have an '__iter__'
attribute. The basic list of object classes of this group are,
- strings (
'str'
classs)
- lists (
'list'
class)
- tuples (
'tuple'
class)
- sets (
'set'
class)
- dictionaries (
'dict'
class)
How can we confirm the above? With another built in function, hasattr()
.
print (hasattr({'a': 42}, '__iter__') # True
The object given in the argument above is a dict
.
So, len()
returns the number of countable elements in an iterable object.
print (len('This is a string.')) # 17
Notice that spaces and non-letter characters are also counted since they make up some of the elements (characters) of the string.
print (len([1,2,3,4,5,6,7,8,9])) # 9
The list above contains nine countable elements (cells).
Other than reporting the number of countable elements in an iterable, the len()
function has no other purpose intended or otherwise. That is its functional value: report length. Don’t read anything else into this.
print (len('Supercalifragilisticexpialidocious')) # 34
Another term we often find associated with iterable objects is, ‘sequence’. The terms are practically synonymous.
A string is a non-mutable sequence of characters (letters, numbers, spaces, punctuation, etc.).
A list is a mutable sequence that may be either homogeneous (all the same type) or heterogeneous (mixed types). We say it is mutable because we can alter the list in any number of ways such as their order, their values, the number of values, or the list itself.
The tuple is a non-mutable sequence, meaning we can neither change the order, the values or the tuple itself. It is frozen in its present state.
Now we come to the built in range()
function, which is a type of sequence generator. The sequence is always integers, and the arguments we give the function are always integer. The object returned is called a, range object
and in its returned form, has no ‘size’, only its specified starting value, the upper (or lower in the case of negative direction) non-inclusive limit, and the step or stride value. These are, as stated, always given as integers.
print (range(3, 33, 3)) # range(3, 33, 3)
Even though it has no size beyond ~48 bytes of memory, it is iterable and does have countable elements, meaning it has a length.
print (len(range(3, 33, 3)) # 10
We needn’t cast the range object to a list if all we wish to do is iterate over it.
for x in range(3, 33, 3):
print (x)
3
6
9
12
15
18
21
24
27
30
Count them; are there ten elements in the sequence?
Bottom line, len()
and range()
have no direct affiliation with each other, they are just commonly used together in combined purpose fashion, nothing more. A range object will always be a defined sequence, and len()
will always count the number of elements in the sequence. Don’t mix these two up or think that they are dependent upon each other. They are not.