Why don't we have to initialize the variable of a for loop?

Question

In Python, why don’t we have to initialize the variable of a for loop?

Answer

In Python, a for loop variable does not have to be initialized beforehand.

This is because of how Python for loops work. When it runs, the for loop statement will initialize the variable to the first character of the string, and continue updating its value to the subsequent characters in the string, until the loop reaches the final character or is terminated before that.

Example

# This initialization is not necessary!
i = 0

# i is initialized to the first character, "1"
for i in "12345":
  print(i)

# The output will be
# 1 
# 2
# 3
# 4
# 5
4 Likes

by “we don’t have to initialize the variable of a for loop”
I thought you were maybe talking about this (but weren’t):

for _ in “12345”:

If the variable is never used, then you don’t have to initialize it!
Just something I thought I’d add (I just finished a course in Haskell and Rust, but never have done anything in python – so far it seems a lot easier haha)

1 Like

Does it mean Python doesn’t have/need the increment-decrement operators unlike other languages?

Not with for x in y:, which will step through an iterable (list, string, range(), many others), y and one at a time, assign its elements to x.

2 Likes

Other languages offer a means by which we can access the value by index, or by direct reference, just as Python does. The increment operator is typically used in a for loop of the C like languages, but not explicitly in Python. Instead we use a range object to supply a sequence of our choosing, which we may iterate.

The direction that comes from ++1 or --1 is achieved with a positive or negative direction on the range. Same effect, different means.

3 Likes

Hi, @mtf,
I’m from a java background and I generally use i++ or count++ to increment by one, but in python, I am Using
i+=1 or count+=1 for increment by one and if I use count++ in python to increment it by one like in java I get an error like (I used length as my variable here)

length++
           ^
SyntaxError: invalid syntax

so Python doesn’t support this type of operation for increment?
Thanks in advance!

Correct, the ++ and -- operators are not supported.

5 Likes

Hello sir/mam,
I got error in this unit of strings.
I got correct output of mention how many characters are there in a string!

Here is my code:

def get_length(strings):

for letter in strings:

print(letter)

strings = “SATYAMEVA JAYATE”

counter = 0

for letter in strings:

counter +=1

print(len(strings))

got here OUTPUT of 16

*STILL IT DOES NOT ALLOWING ME TO GO FOR NEXT UNIT
GOT MANY TIMES THESE TYPE OF ERRORS even after getting a correct output

// Please help :slight_smile:

@ design1233448968

There are several errors here to mention:

1: Using the “len” funtion was not allowed here.
2. The “auto-diffing” tool for Codecademy was expecting the function “get_length()” to be called. Here it was not.
3. The 'auto-diffing" tool for Codecademy was expecting the “counter” variable to be defined inside the “get_length()” function.
4. And the “auto-diffing” tool for Codecademy was expecting the variable “counter” defined inside the “get_length()” function to be “return”'ed at the end of the function.

***See if you can rearrange your source code to correct the errors mentioned above and see if you can “continue”.

Iterating through Strings Instructions: Let’s replicate a function you are already familiar with, len().
Write a new function called get_length() that takes a string as an input and returns the number of characters in that string. Do this by iterating through the string, don’t cheat and use len()!
Concern:
I am new on coding, and python is the first language I am learning. But there are some cases that I get confused with the instructions like above “…, don’t cheat and use len()!” I thought I had to use only len( ) within my function.
I just need some motivation to not think coding is not for me. I was not be able to think of using:
counter = 0
for letter in word:
counter += 1
return counter
I focused only on using len( ) rather than the function above.
I will just moving on. :sweat_smile:

A large part of programming is about ideating algorithms. There is much we can do without reaching too far into the Standard Library just by using loops and control flow. The above example is what we would be doing if there was no such function as, len(). We would write our own.

We know that a word is a form of string data, and STR is an iterable, so that means we can iterate over each letter in the word. The action we take on each iteration, for the above, is to increment our counter. The end result will be the length of the word.

Don’t let stuff like this frustrate you. Focus on the main process: ideating an algorithm (steps that can be repeated in order, &c.)

3 Likes

Thank you sir. :raised_hands: I will keep it up and and start ideating an algorithm and try to think outside the box.

1 Like

Can someone give a review of my code ?
def get_length(strings, counter):
for letter in strings:
counter += 1
return counter

test = "The way I understand this is that the len() function returns an absolute value "
count = 0

exercice = get_length(test, count)
print(exercice)

Absolute in terms of being positive or zero, and never negative. The return will be an integer of the physical element count of the iterable. Only iterable objects can have a length.

Aside

When a variable points to a singular object, then a singular term would be more apt than a plural one. strings implies more than one string, such as a list of strings.

strings = [ 'one', 'two', 'three', 'four' ]

for string in strings:
    pass

So for the above, a reader might make more sense of the signature line if it is written like so,

def get_length(string):
    pass

I would also not pass in the counter variable, but rather declare it inside the function so it always starts at zero.

def get_length(string):
    counter = 0
    for char in string:
        pass

Again, the name we give a variable is arbitrary but it helps if it conveys meaning to the reader. Above I chose char as my variable since while all letters are characters, not all characters are letters. The meaning of ‘char’ conveys generally, where as ‘letter’ conveys specifically. Semantics, eh? Not deal breaking, but ever useful to the reader when we think in those terms.

Okay, so what we have here is a function to count the number of elements in an iterable, be that a string, a list, a tuple, a set, even a dictionary (key count). Taking this into account, we can rewrite our function to convey that any iterable can be accepted.

>>> def get_length(iterable):
...     if not hasattr(iterable, '__iter__'):
...         raise ValueError
...     count = 0
...     for element in iterable:
...         count += 1
...     return count
... 
>>> get_length(36535)
Traceback (most recent call last):
  File "<pyshell#56>", line 1, in <module>
    get_length(36535)
  File "<pyshell#55>", line 3, in get_length
    raise ValueError
ValueError
>>> get_length("The way I understand this is that the len() function returns an absolute value ")
79
>>> get_length({1: 'a', 2: 'b'})
2
>>> get_length([5, 4, 3, 6, 7, 8, 1, 2, 9])
9
>>> get_length((2, 4, 6, 8, 10))
5
>>> get_length({6, 2, 8, 9, 1, 4})
6
>>> get_length(True)
Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    get_length(True)
  File "<pyshell#55>", line 3, in get_length
    raise ValueError
ValueError
>>> 

This can go on the back burner, for now, as I suspect you will not have covered everything in the code. but you should be able to get the gist.

1 Like

def get_length(string):
counter = 0
for character in string:
counter += 1
return counter

print(get_length(string)

This is how I updated the code regarding your comment.
I don’t understand this part :
… if not hasattr(iterable, ‘iter’):
… raise ValueError

I don’t understand where it adds value to our code.
I don’t understand the output you get, I think it’s connected to the “raise ValueError” but I don’t see how and why:

get_length({1: ‘a’, 2: ‘b’})
2
get_length([5, 4, 3, 6, 7, 8, 1, 2, 9])
9
If you ever come back and have time to clear this out, it would be lovely,
thanks again for your help, have a good day !

In Python, all objects trace back to a class, whether built in or custom. As we know, classes have attributes that refer to data, and attributes that refer to methods. The hasattr() built in function lets us examine an object to see if it has a particular attribute.

class Foo:
    def __init__(self, bar):
        self.bar = bar

# instantiate an object of the Foo class

>>> foo = Foo("Baz")
>>> print (hasattr(foo, 'bar'))
True
>>> print (foo.bar)
Baz
>>>

In the earlier example we use the function to test if the argument is an iterable or not. If it has inherited the __iter__ attribute then we know it can be iterated since that is the method that is behind the scenes in a for loop.

Another aspect of programming is error checking/trapping and handling. Python has a built in Exception class that is triggered when runtime errors are encountered.

We used preemptive exception handling in the example that raises a ValueError exception (our call) if the argument is not iterable. The choice of which exception to raise was my own, but in this case it tells the user that the value they have given as an argument is not valid input. Normally, if we allow any input and the user hands in a number, Python will raise its own exception:

for x in 1089:
    print (x)

    
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    for x in 1089:
TypeError: 'int' object is not iterable

The value it adds is the ability to validate user inputs before they raise an exception. In the example we kill the program but in reality we could give the user a message and let them try again without killing the program.

Errors and Exception Handling is a unit in the Python 3 course, so it will come up in due time. For now, if you have time you can get ahead of that with some reading on the subject. The unit will be a breeze if you are prepared for it.

I see better, thank you for this explanation, I will look around some documentation and try to use it from now on.
As I understand, using ValueError will allow me to see the problem before the code fail, and this will help me better see where precisely it failed ?

In your example :
for x in 1089:
print(x)

It fails because 1089 cannot be iterated, if I had used “hasattr(iter)” it would have told me “1089” is not iterable before the code fail ?

Correct. We would then direct the flow away from the code that would normally raise an exception (a fatal error) to a warning message and a chance to try again. We would stipulate the handling of the error, rather than let Python do it.

Note that ValueError is the name of the Exception instance. The keyword used to halt the program is raise, as in,

raise Exception

The above is a rather simplified example (still causes the program to halt rather than being directed to a custom exception handler). More on this you will learn in time so don’t let it interrupt you learning path. Put a pin in it, for now and keep up your progress.

1 Like