0 / 0 / 0
Регистрация: 18.03.2014
Сообщений: 24

Прерывание рекурсии

08.06.2016, 10:03. Показов 8956. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Знатоки, ну помогите. Код ниже делает обход вложенных словарей и при нахождении необходимого ключа должен свернуть все открытые рекурсии и вернуть значение self.Type = FeatureClass. Но сворачивает только нижний поток и упорно возвращается выше, естественно заменяя значение self.Type на пустое значение в своём пространстве имён. Как после выполнения условия if sField in listGeometryFields остановить все порождённые рекурсии и выйти из функции?
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class DefineDataFromDictionary:
    def __init__(self, dictLayer):
        self.dictLayer  = dictLayer
           
    def DefineTypeLayer(self, sLayer, bStopRecursion = False):
        try:
            self.sLayer       = sLayer
            self.bStopRecursion = bStopRecursion
            self.Type         = ''
            
            if len(self.dictLayer[self.sLayer]) == 0:
                self.Type = 'empty data'
                self.bStopRecursion = True
            
            if not self.bStopRecursion:
                for sField in self.dictLayer[self.sLayer]:                
                    if sField in listGeometryFields:
                        print 'finded!!!!'
                        self.Type           = sFeatureClassType
                        self.bStopRecursion = True
                        return self.Type
                        
                    if type(self.dictLayer[self.sLayer]) == dict:
                        print 'new recursion!!!!'
                        self.objSubDict = DefineDataFromDictionary(self.dictLayer[self.sLayer])
                        self.objSubDict.DefineTypeLayer(sField, self.bStopRecursion)
                        del self.objSubDict
                
            if self.Type == '':
                self.Type = sTableType
                
            return self.Type
        except:
            tb = sys.exc_info()[2]
            print 'ERROR\tFail to execute script'
            print 'Line ' + str(tb.tb_lineno)
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.06.2016, 10:03
Ответы с готовыми решениями:

Прерывание цикла while
Как сделать прерывание цикла (аргумент while), если прога не выводит какое-либо сообщения в командной строке? Просто прога создана для...

Прерывание программы по таймеру
Как мне создать собственное исключение для прерывания функции, если она выполняется дольше 1 секунды?

Прерывание запроса на сервер
Здравствуйте! Сайт написан на Python 2.6 Реализована передача данных на сервер в два этапа с последующими ответами сервера так же в два...

5
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
08.06.2016, 10:26
Видимо, потому что у вас в объекте порождается ещё один, который self.objSubDict. Отсюда путаница. Не надо так делать, пусть функция вызывается в этом же объекте.
0
0 / 0 / 0
Регистрация: 18.03.2014
Сообщений: 24
08.06.2016, 11:02  [ТС]
В экземпляре класса у нас уже есть словарь. Т.е. его не использовать, а передавать его ещё раз в функцию? Как то тоже некрасиво... Буду делать без объекта self.objSubDict, думала есть способ их всех сразу прибить.
0
Эксперт Python
 Аватар для dondublon
4652 / 2072 / 366
Регистрация: 17.03.2012
Сообщений: 10,182
Записей в блоге: 6
08.06.2016, 15:32
Цитата Сообщение от NetPixie Посмотреть сообщение
В экземпляре класса у нас уже есть словарь. Т.е. его не использовать, а передавать его ещё раз в функцию?
Передавать не его, а содержащийся в нём дочерний словарь. По-моему, это очевидно следует из сути рекурсии.

Зачем вам лишний объект, он вообще не при делах тут. Он начнёт свою рекурсию, там не разберётесь вообще никогда.

Добавлено через 11 минут
Держите.
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
d = {10: 2, 4: 8, 9: 7, 11:{14: 13, 33: 21, 3: {56: 19}}, 13: {16: 26}}
 
def rec_find(dic, pred):
    for k, v in dic.items():
        if type(v) is dict:
            found, res = rec_find(v, pred)
            if found:
                return True, res
        else:
            found = pred(k)
            if found:
                return True, (k, v)
    return False, None
 
print (rec_find(d, lambda k: k==33))
Добавлено через 6 минут
Пардон, косячок. Вот так надо:
Python
1
2
3
4
5
6
7
8
9
10
11
def rec_find(dic, pred):
    for k, v in dic.items():
        found = pred(k)
        if found:
            return True, (k, v)
 
        if type(v) is dict:
            found, res = rec_find(v, pred)
            if found:
                return True, res
    return False, None
0
440 / 432 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
08.06.2016, 15:42
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class DefineDataFromDictionary:
    def __init__(self, dictLayer):
        self.dictLayer  = dictLayer
           
    def DefineTypeLayer(self, sLayer):
        try:
            self.sLayer       = sLayer
            self.Type         = ''
            
            if len(self.dictLayer[self.sLayer]) == 0:
                self.Type = 'empty data'
                return self.Type
            
            for sField in self.dictLayer[self.sLayer]:                
                if sField in listGeometryFields:
                    print 'found!!!'
                    self.Type           = sFeatureClassType
                    return self.Type
                        
                if type(self.dictLayer[self.sLayer]) == dict:
                    print 'new recursion!!!!'
                    self.Type = self.DefineTypeLayer(sField)
                
            if self.Type == '':
                self.Type = sTableType
                
            return self.Type
        except:
            tb = sys.exc_info()[2]
            print 'ERROR\tFail to execute script'
            print 'Line ' + str(tb.tb_lineno)
как то так может быть
0
0 / 0 / 0
Регистрация: 18.03.2014
Сообщений: 24
09.06.2016, 12:00  [ТС]
oldnewyear, так не пойдёт, у меня
sLayer = 'node',
dictLayer[self.sLayer] - {'node': {'coordinate': {'lat': ["<type 'float'>", u'20.1119003296'], 'zlevel': ["<type 'int'>", u'0'], 'lon': ["<type 'float'>", u'-102.564788818'], 'z_coord': ["<type 'int'>", u'0']}, 'node_id': ["<type 'long'>", u'1121999621'], 'is_aligned': ["<type 'bool'>", u'False']}}
Будет крутиться на одном месте передавая в sField 'node' и выходя на рекурсию.

Добавлено через 32 минуты
dondublon, это работает, сохраню себе на будующее, спасибо.
Я вчера всё-таки сделала с созданием нового объекта класса в классе. Но не так как хотелось раньше. Мне всё равно нужен был полный список полей, я его вычитала, а потом просто по нему прошлась, определяя есть ли нужное мне. А просто список, без прерывания номально вычитывает:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class DefineDataFromDictionary:
    def __init__(self, dictLayer):
        self.dictLayer  = dictLayer
    def DefineListFields(self, sLayerWithFields, sFullFieldName = '', listFields = []):
        try:
            self.sLayerWithFields   = sLayerWithFields
            self.listFields         = listFields
            
            for sField in self.dictLayer[self.sLayerWithFields]:
                if type(self.dictLayer[self.sLayerWithFields]) == dict:
                    self.objSubDict = DefineDataFromDictionary(self.dictLayer[self.sLayerWithFields])
                    self.objSubDict.DefineListFields(sField, sFullFieldName + '.' + sField, self.listFields)                    
                    del self.objSubDict
                else:                    
                    if sFullFieldName != '':
                        sFullFieldName = sFullFieldName[1:]
                        self.listFields.append([sFullFieldName, sTypeField])
                    sFullFieldName = ''
                   
        except:
            tb = sys.exc_info()[2]
            print 'Line ' + str(tb.tb_lineno)
            print str(sys.exc_info()[:2])
        return self.listFields
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
09.06.2016, 12:00
Помогаю со студенческими работами здесь

Прерывание выполнения программы
Как сделать так, чтобы выполнение программы прерывалось при определённой введённой команде? Даже если в этот момент выполняется что-то...

Ввод списка с клавиатуры и прерывание при 0
Здравствуйте. По заданию нужно ввести список с клавиатуры, при этом если вводиться 0, должно произойти прерывание, но пользоваться if...

Python Прерывание цикла зажатой клавишей
import os import time import win32api, win32con from numpy import * #Дальше идёт цикл: ... Где-то внутри цикла мне нужны...

Вычисление числа а в степени b с использованием рекурсии и без использования рекурсии
Реализуйте приложение, которое будет производить вычисление по формулам двумя способами: с использованием рекурсии и без использования ...

Вывести на экран результат возведения в степень числа с помощью рекурсии, подсчитать уровень рекурсии.
Задание: Вывести на экран результат возведения в степень числа с помощью рекурсии, подсчитать уровень рекурсии. Я и так знаю что даже ход...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

Новые блоги и статьи
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru