Skip to content
Advertisement

Iterating through a function returned 2-tuple containing two lists?

I am trying to learn the PIL’s image library and I am stuck yet a second time. What I am trying to do is read through a directory and all its subdirectories and only load, rotate and replace the images in a specific path entered by the user (or specified in the script). The problem is that line () in the code where I try to iterate through a function returned 2-tuple containing a list containing Imageobjects and another list containing strings raises the error:

“ValueError: too many values to unpack (expected 2)”.

I have tried doing a similar function in a separate script that returns the same type of 2-tuple that the get_subdirectory_images() function returns only without using any modules.

The real file with the error:

try:
    from PIL import Image
    from PIL import ImageEnhance
except ImportError:
    print("Please install Pillow using pip" + "nn")

import os

inp = "C:\Users\Isak Blomster\AppData\Roaming\.minecraft\resourcepacks\The python script pack\assets\minecraft\textures\items"
os.path.relpath(str(inp))

def get_subdirectory_images(target_directory_list, file_extension):

    images = []
    image_paths = []

    for current_directory, subdirectory_names, file_names in os.walk("."):

        tupl = (current_directory, subdirectory_names, file_names)
        #print(tupl)

        for target_directory in target_directory_list:

            if os.path.realpath(target_directory) == os.path.realpath(current_directory):
                #print("test")

                for name in file_names:

                    if name.endswith(file_extension):

                        image_path = os.path.join(current_directory, name)
                        image = Image.open(image_path)

                        images.append(image)
                        image_paths.append(image_path)

    return images, image_paths;

#print((get_subdirectory_images([str(inp)], ".png")))
for images, paths in get_subdirectory_images([str(inp)], ".png"):
    print("Test")
    rotated = images.rotate(90)
    rotated.save(paths)

Which returns this when run:

ValueError: too many values to unpack (expected 2)

This is a small scale which I seemingly got to work as I wanted?

class Image:
    """docstring for Image"""
    x = 0
    def __init__(self, x):
        self.x = x

    def give_xy(self, y):
        xy = self.x * y
        return xy
i = 0

def function(num1, num2):

    A = Image(num1)
    B = Image(num2)

    string_list = ["wow", "wow2"]
    object_list = [A, B]

    return string_list, object_list

for a, b in function(1, 2):
    i += 1
    if i > 1:
        print(a.give_xy(3), b.give_xy(4))

And it returns

3 8

The expected result is that all the images in the items subfolder should be rotated 90 degrees.

Advertisement

Answer

return images, image_paths

your function returns one tuple containing two lists of the same size.

Now the for loop iterates on the result, and first yields images which is a list of images (more than 2 images) that cannot fit in 2 variables. That explains the error message.

You could have built a dictionary or a list of tuples instead but if you want to iterate/associate images & paths you have to iterate on the zipped result

for images, paths in zip(*get_subdirectory_images([str(inp)], ".png")):

(variable names should be image, path, would be more logical)

As I mentionned above, returning a tuple of 2 lists, which must be associated together to be properly processed isn’t a good way of doing it.

Instead of doing:

images.append(image)
image_paths.append(image_path)

just use images = [] at start, then:

images.append((image,image_path))

then

return images

now your unpacking works fine since each image/path tuple is associated when building the data structure.

Advertisement