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

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

08.06.2016, 10:03. Показов 7666. Ответов 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.06.2016, 10:03
Ответы с готовыми решениями:

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

Ошибка в рекурсии
Помогите пожалуйста исправить ошибку. Задание: Найти сумму наименьших элементов. import random...

Оптимизация рекурсии
нужно проходить дерево и найти самую длинную ветку.. Написал код, все работает, но нужно...

Глубина рекурсии и поведение программы
Вычисляю факториал: def fact(n): if n == 0: return 1 return fact(n - 1) * n...

5
Эксперт Python
4607 / 2028 / 359
Регистрация: 17.03.2012
Сообщений: 10,086
Записей в блоге: 6
08.06.2016, 10:26 2
Видимо, потому что у вас в объекте порождается ещё один, который self.objSubDict. Отсюда путаница. Не надо так делать, пусть функция вызывается в этом же объекте.
0
0 / 0 / 0
Регистрация: 18.03.2014
Сообщений: 24
08.06.2016, 11:02  [ТС] 3
В экземпляре класса у нас уже есть словарь. Т.е. его не использовать, а передавать его ещё раз в функцию? Как то тоже некрасиво... Буду делать без объекта self.objSubDict, думала есть способ их всех сразу прибить.
0
Эксперт Python
4607 / 2028 / 359
Регистрация: 17.03.2012
Сообщений: 10,086
Записей в блоге: 6
08.06.2016, 15:32 4
Цитата Сообщение от 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
438 / 430 / 159
Регистрация: 21.05.2016
Сообщений: 1,338
08.06.2016, 15:42 5
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  [ТС] 6
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
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.06.2016, 12:00
Помогаю со студенческими работами здесь

Объясните механизм рекурсии (Лутц стр. 539)
Всем привет. В программировании новичек(сам верстальщик сайтов) и сейчас читаю лутца. Пытаюсь...

Вычисление суммы списка с вложенными списками посредством рекурсии
Добрый вечер. Занимаюсь самоизучением Python и столкнулся с рекурсивными функциями. Пример был...

Работа рекурсии Python3
В программе по вычислению определителя матрицы использую рекурсивный алгоритм. Если вкратце, то...

неправильная работа рекурсии в некоторых случаях
Неправильно работает рекурсия для некоторых чисел(умножение Карацубы), подскажите пожалуйста как...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru