цикл по спискам каталогов list.remove() не работает

Я пытаюсь просмотреть несколько каталогов и несколько GDB, чтобы создать список классов объектов. Проблема, с которой я сталкиваюсь, заключается в том, что когда я пытаюсь удалить определенные классы объектов из списка, сценарий просто игнорируется или я получаю сообщение об ошибке, в котором говорится, что x не существует в списке (x). Проблема с именами классов объектов заключается в том, что они имеют 3 буквы, которые уникальны для каждой GDB, но при этом имеют 2 других стандартных компонента.

Что-то вроде этого:

directory1 > directory1.gdb > фигуры > fc_dir1_feature

&

directory2 > directory2.gdb > фигуры > fc_dir2_feature

и так далее...

Я использую

for dirpath, dirnames, filenames in arcpy.da.Walk(in_workspace, datatype="FeatureClass",type="Polygon"):
if "dir1" in dirnames:
    dirnames.remove('dir1')

Это прекрасно работает для удаления наборов данных объектов из GDB и, соответственно, всех классов объектов внутри. Но я не могу удалить только определенные классы объектов.

Спасибо за любую помощь.


person cbrannin    schedule 23.05.2013    source источник
comment
Код, который вы показываете, ничего не фильтрует... у вас нет каталогов с именем «dir1». Вам нужен внутренний цикл for, который перебирает имена каталогов и проверяет, находится ли «dir1» в одном из них.   -  person tdelaney    schedule 23.05.2013
comment
Да, этот фрагмент скрипта удалит весь каталог и классы объектов внутри. Вот где моя проблема, я не хочу, чтобы весь каталог исчез с некоторыми классами объектов в каталоге.   -  person cbrannin    schedule 23.05.2013
comment
у вас есть каталог с именем «directory1» и каталоги, такие как «fc_dir1_feature», которые содержат «dir1», но нет каталогов с именем «dir1». Итак, если ваш оператор if действительно if "directory1" in dirnames:, у вас возникнет эта проблема. Я думаю, что знаю, как это решить, и напишу ответ.   -  person tdelaney    schedule 23.05.2013
comment
О да, мне жаль, что ты прав. И это как раз моя проблема. «dir1» — это просто пример того, что единственная часть имени файла отличается в каждом каталоге. Извините, я не очень хорошо объясняю. Я пробовал что-то вроде этого: «код», если набор данных в именах каталогов: для имени файла в именах файлов, если имя файла.startswith («sl_») и имя файла.   -  person cbrannin    schedule 23.05.2013


Ответы (1)


Предполагая, что arcpy.da.Walk работает так же, как os.walk (то есть удаление каталога из имен каталогов останавливает переход к этому каталогу), вы должны добавить еще один цикл for для перебора имен каталогов и применения вашего фильтра. Обратите внимание, что я скопировал имена каталогов, чтобы вызывать remove, не нарушая работу итератора.

for dirpath, dirnames, filenames in arcpy.da.Walk(in_workspace, datatype="FeatureClass",type="Polygon"):
    # remove subdirectories that match pattern so they will not be walked
    for dirname in dirnames[:]:
        if 'dir1' in dirname:
            dirnames.remove(dirname)

Взяв из ресурсы ArcGIS, вы можете использовать регулярное выражение для фильтрации имен файлов несколькими способами. Вот примеры регулярного выражения, которое удаляет файлы, содержащие «abc», «def» или «ghi» в слотах подстановочных знаков:

import arcpy
import os
import re

workspace = "c:/data"
feature_classes = []

# i dont like abc, def or ghi features so I have a regex to match them
filter_classes_re = re.compile('fc_(abc|def|ghi)_feature$')

for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,
                                                  datatype="FeatureClass",
                                                  type="Polygon"):
    for filename in filenames:
        # only add to feature list if it doesn't match the bad guys
        if filter_classes_re.match(filename) is None:
            feature_classes.append(os.path.join(dirpath, filename))


# alternately, i could extract the wildcard part and compare it outside
# of the regex ... but this will be slower

filter_classes_re = re.compile('fc_(.*?)_feature$')

for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,
                                                  datatype="FeatureClass",
                                                  type="Polygon"):
    for filename in filenames:
        # extract the wildcard part
        match = filter_classes_re.match(filename)
        if match:
            matched = match.group(1)
        else:
            matched = ''
        if matched not in ('abc', 'def', 'ghi'):
            feature_classes.append(os.path.join(dirpath, filename))
person tdelaney    schedule 23.05.2013
comment
Проблема в том, что я пытаюсь ограничить файлы в каталоге. Мне все еще нужно пройтись по каталогам и удалить определенные файлы. Файлы помечены как «fc_.*_feature». Я попытаюсь применить ваш скрипт выше для работы с именами файлов, это вообще сработает? - person cbrannin; 23.05.2013
comment
Да, вы можете сделать то же самое с именами файлов. Поскольку имена файлов не нужны для дальнейшей итерации, вы создаете новый список требуемых_файлов, перебираете имена файлов и вставляете в список только те, которые вам нужны. Тогда вы должны использовать список где-нибудь, конечно. - person tdelaney; 23.05.2013
comment
Я не знаю/понимаю, как быть с тем фактом, что в именах файлов есть подстановочный знак (fc_[wildcard]_feature. Я просматриваю сотни каталогов, и есть несколько таких файлов, которые нужно исключить. Все еще я пытался был проигнорирован. - person cbrannin; 23.05.2013
comment
@cbrannin Я добавил второй пример, который показывает пару способов использования регулярных выражений для фильтрации ваших файлов. - person tdelaney; 23.05.2013
comment
Если я правильно понимаю, у меня должны быть где-то все подстановочные знаки, чтобы любой из них работал? - person cbrannin; 23.05.2013
comment
@cbrannin - я не уверен, что тебе нужно. насколько я понимаю, вы хотите удалить некоторые файлы fc_.*_feature и оставить другие. Вам нужны некоторые критерии (я использовал вещи с именами «abc», «def», «ghi»), чтобы принять решение. Каковы ваши критерии? Это то, что вы используете, чтобы соответствовать. - person tdelaney; 23.05.2013
comment
Когда список компилируется, он по-прежнему игнорирует поиск только части функции в имени файла. Весь список компилируется с каждым слоем, который находится в подкаталогах. Я пытаюсь обойти подстановочный знак, чтобы фильтровать функцию (fc_[wild]_feature). Я даже не уверен, что объясняю это очень хорошо. Извините и еще раз спасибо за всю помощь. - person cbrannin; 23.05.2013