Неправильный порядок итерации по папке и печати имен файлов - PullRequest
0 голосов
/ 28 февраля 2020

Пожалуйста, помогите с попыткой напечатать имена файлов картинок. Я либо печатаю то же имя файла или то же изображение с другим именем файла.

Я хочу, чтобы вывод был FileName, а затем Pic, связанный с FileName. Вместо этого я получаю FileName0 и Pic0, затем FileName0, затем Pic1 или Filename0, затем Pic0, затем Filename1, затем Pic0.

Я добавил еще код к исходному сообщению. для разъяснения того, что я пытался сделать. Надеюсь, я / это имеет смысл. Я хочу напечатать название изображения, а затем отобразить изображение. Новый код, который я придумал, отображает изображение, затем печатает имя внизу, и программа завершается. Скажем, в списке 4 изображения. Я хочу напечатать имя на изображении [0] и затем отобразить изображение [0] в al oop, а затем напечатать изображение [1] отобразить изображение [1]

#OLD CODE
with zipfile.ZipFile("file.zip", 'r') as zip_ref:
    zip_ref.extractall("folderName")

    for info in zip_ref.infolist():
        for file in os.listdir("folderName"):
            image=Image.open(file).convert('RGB') 

            print(info.filename)
            display(image)

#NEW CODE
#My current list length is 4
file_name = []
actual_image = []
##Extract all the files and put in folder
with zipfile.ZipFile("readonly/small_img.zip", 'r') as zip_ref:
    zip_ref.extractall("pyproject")

#Add name to list/Add image to list.  Probably should be one list.
for entry in os.scandir("pyproject"):
    file_name.append(entry.name)
for file in os.listdir("pyproject"):
    image=Image.open(file).convert('RGB')
    actual_image.append(image)
#print(info.filename,display(image)) 

#Newer line of code directly above.  
#When the above for loop becomes nested it displays 4 
#pictures with the file number underneath.  Expected result is 1pic to 1 filename.  
#Its closer to what I want.  Will keep trying.

print(len(file_name))

#Returns file names.
def name_of_file(a):
    for names in a:
        return names

#Returns image to be displayed
def image_of_file(b):
    for image in b:
        return (display(image))
##Prints out image name and then displays image
print(name_of_file(file_name),image_of_file(actual_image))

###Dictionary example code:
list_of_pictures = [{image1_of_four :PIL.image,bounding_box,pytesseract_text}]

1 Ответ

0 голосов
/ 28 февраля 2020

Я думаю, что путаница возникает из-за двойной итерации. Насколько я вижу, в этом нет необходимости, потому что вы просто хотите перебирать каждый (образ) файл в заархивированном каталоге. (Если я правильно понял вопрос.)

Здесь достаточно одной итерации:

import zipfile

with zipfile.ZipFile("file.zip", 'r') as zip_ref:
    for file in zip_ref.filelist:
        print(file.filename)
        # ...

Так что для обработки файлов внутри zip-архива вы можете сделать что-то вроде этого (конечно, есть несколько возможностей, в зависимости от варианта использования):

import zipfile
from PIL import Image, UnidentifiedImageError

with zipfile.ZipFile("file.zip", 'r') as zip_ref:
    for zipped_file in zip_ref.filelist:
        print(f"This is your fileinfo: {zipped_file.filename}")
        try:
            file = zip_ref.open(zipped_file)
            image = Image.open(file).convert('RGB')
        except UnidentifiedImageError:
            print(f"Error processing {zipped_file.filename}")

Если вам действительно нужна дополнительная информация из повторяющихся (заархивированных) файлов, то infolist() метод в порядке, предоставляя вам информацию из ZipInfo -объекта.

Обновление после редактирования вопроса :

Насколько я вижу, остается изображение для отображения и соответствующее имя файла для печати. Если мое предположение верно, то есть несколько проблем с представленным кодом:

  • Нет необходимости повторять несколько раз. Неважно, есть ли у вас одна вложенная итерация или несколько итераций подряд. Ограничение количества итераций также уменьшает сложность и, вероятно, все становится менее сложным. Подробнее о go: Вы используете несколько итераций, чтобы: 1. разархивировать файлы (zip_ref.extractall() уже выполняет итерацию), 2. сохранить имена файлов в списке, 3. сохранить объекты изображений в списке, 4. распечатать сохраненные имена файлов, 5. отображать изображения объектов. Вся информация уже доступна вам при переборе файлов в архиве или может быть легко вычислена на текущем шаге итерации. Это полностью исключает необходимость создания нескольких структур данных для имен файлов, объектов изображений и т. Д. c. Здесь у вас уже есть файл, таким образом, также имя файла и, соответственно, соответствующее изображение.
  • Я все еще не вижу смысла сначала распаковывать весь архив. Все это можно сделать в самой итерации. Если сами изображения должны быть сохранены, то распаковка, конечно, полезна. Но затем вы можете просто разархивировать файлы, а затем перебрать разархивированные файлы с помощью Python, например, os.scandir(). Это было реализовано в обновленном коде. Но в этом нет необходимости, если вы хотите отображать текущий файл каждого шага итерации.

К сожалению, функция display() до сих пор мне не известна. Вероятно, там делается нечто похожее на Image.show(). После обновления кода в вопросе я могу упомянуть лишь небольшие изменения в своем примере, чтобы показать, насколько просто можно отобразить имя файла для соответствующего изображения:

import os
import zipfile
from PIL import Image, UnidentifiedImageError


with zipfile.ZipFile("file.zip", 'r') as zip_ref:
    for zipped_file in zip_ref.filelist:
        try:
            image = Image.open(zip_ref.open(zipped_file)).convert('RGB')
            print(os.path.basename(zipped_file.filename))
            image.show()  # simulating: display(image)
            input("Press a key to show next image...")
        except UnidentifiedImageError:
            pass

Я печатаю только имя файла, для которого также есть соответствующая картина. Никаких других отпечатков (чтобы все было как можно яснее). image.show() используется для имитации неизвестной display(image) -функции. Чтобы прояснить, что соответствующее имя файла относится к открытому в данный момент изображению, я включил паузу в форме приглашения пользователя (input()).

Все это при условии, что просто соответствующее имя файла для определенного изображения должно отображаться. Здесь уместно использовать только одну итерацию.

Использование нескольких итераций для хранения объектов в нескольких списках (как сделано в вопросе) приводит к недостатку: более высокая сложность. В этом случае позиции индексов в списках должны совпадать, и при итерации по одному списку вы должны получить доступ к другому списку с такой же позицией индекса, как этот:

list_a = [1, 2, 3]
list_b = ["a", "b", "c"]
for index, el in enumerate(list_a):
    print(el, list_b[index])

Вы должны сделайте это, не меняя большую часть вашего кода. Но тогда вы должны убедиться, что списки никогда не меняются (или, скорее, использовать кортежи), и это просто более сложно (и также более сложно). См. Также this .

...