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