Anay Bose Anay Bose - 3 months ago 8
Python Question

within python for loop calling more than one functions

the following code filters images, now I would like to call two functions for each image in a for loop one by one; first

check_image_size
and then
binarization
. I am having trouble figuring out the correct syntax.

import os, sys

check_image_size(pic)
binarization(pic)

folder = '../6'
names = [check_image_size(os.path.join(folder, name))
for name in os.listdir(folder)
if not name.endswith('bin.png')
if not name.endswith('.jpg')
if not name.endswith('.nrm.png')
]

Answer

What you are doing here is not the actual way to define a for loop. What you are using is list comprehension.

What is list comprehension?

List comprehension is used to quickly equate values for loops. For example:

x = []
for i in range(10):
    if i % 2 == 0:
        x.append(i)

Is equivalent to:

x = [i for i in range(10) if i % 2 == 0]

Both will give the value of:

>>> x
[0, 2, 4, 6, 8]

Ok... then how is a for loop defined?

A for loop is defined using the for keyword at the start of the statement, not a continuation of a statement. As you can see above, your code can be converted into something like:

# ...
names = []
for name in os.listdir(folder):
    if not name.endswith('bin.png') if not name.endswith('.jpg') if not name.endswith('.nrm.png'):
        names.append(check_image_size(os.path.join(folder, name)))

Now, you would see that you can add more lines after check_image_size(os.path.join(folder, name)) by keeping the same indentation level:

# ...
names = []
for name in os.listdir(folder):
    if not name.endswith('bin.png') if not name.endswith('.jpg') if not name.endswith('.nrm.png'):
        names.append(check_image_size(os.path.join(folder, name)))
        # Add more things here
        my_other_function_to_run(x)
        more_other_functions(y)

My code still doesn't run!

That's because you cannot have more than one if in an if statement. Use and to denote a strictly true relationship instead.

# ...
names = []
for name in os.listdir(folder):
    if not name.endswith('bin.png') and not name.endswith('.jpg') and not name.endswith('.nrm.png'):
        names.append(check_image_size(os.path.join(folder, name)))
        # Add more things here
        my_other_function_to_run(x)
        more_other_functions(y)

Of course, you could do nested if statements but they aren't very nice:

# ...
names = []
for name in os.listdir(folder):
    if not name.endswith('bin.png')
        if not name.endswith('.jpg')
            if not name.endswith('.nrm.png'):
                names.append(check_image_size(os.path.join(folder, name)))
                # Add more things here
                my_other_function_to_run(x)
                more_other_functions(y)

One last note

As I said above, you should not have more than one if keyword in an if statement. This also applies likewise for list comprehension. So your original code should have been:

# ...
names = [check_image_size(os.path.join(folder, name))
         for name in os.listdir(folder) 
         if not name.endswith('bin.png') 
         and not name.endswith('.jpg')  
         and not name.endswith('.nrm.png')
         ]
Comments