Можно ли повторить итерацию цикла? - PullRequest
1 голос
/ 13 июля 2010

Я определил цикл for следующим образом: он просматривает файл, состоящий из двух столбцов, когда находит ключевое слово DEFINE_MENU, второй столбец в этой строке ссылается на заголовок экрана. Следующий экземпляр ключевого слова будет определять заголовок для отдельного экрана и т. Д. На n-м экране. На данный момент код может определять первый заголовок меню.

Возможно ли, когда я достигну второго экземпляра ключевого слова DEFINE_MENU, повторить цикл для той же строки, установив title_flag = 0, повторяя тем самым себя, захватывая заголовок второго меню?

def getInfo():

    title_flag = 0
    number = 1
    menus = {}
    items = {}
    title = None
    file = open('some_file', 'r')
    for line in file:
        # Test for comments, if they exist pass and move on
        if line[0] == '#':
            continue
        # Hop over blank lines
        if re.search(r'^\s+$', line):
            continue
        # Find the line where the title is defined
        if re.search('DEFINE_MENU', line) and title_flag == 0:
            type, name = line.split()
            title = name
            title_flag = 1
            continue
        # If DEFINE_MENU is found and flag has been raised, this
        # signifies a new menu definition so break.
        if re.search('DEFINE_MENU', line) and title_flag == 1:
            break
        if re.search('PRIV', line):
            (type, name, priv_holder, *description) = line.split()
        else:
            (type, name, *description) = line.split()
        # If flag has been raised, the line must follow the definition
        # of the menu, it must contains info regarding a menu item.
        if title_flag == 1:
            description = ' '.join(description)
            items[str(number)] = name
            number += 1
    file.close()
    menus[title] = items
    return menus

Спасибо за ваш вклад!

Tom

РЕДАКТИРОВАТЬ: Во-первых, извинения за вызванную путаницу. Возможно, я думал о проблеме как о более простой, чем я думал, и дал меньше информации, чем требовалось. Я углублюсь глубже, входной файл, который я использую, имеет форму:

# MENU TYPE     NAME            PRIV?   DESCRIPTION
DEFINE_MENU     CRAGINS
MENU            menu_name1              This takes you to menu 1
MENU            menu_name2              This takes you to menu 2
VARIABLE        var_name1               Alter variable1
VARIABLE        var_name2       PRIV    Alter variable1
COMMAND         command1                Perform command1
DEFINE_MENU     MENU2
MENU            menu_name3              This takes you to menu 3
MENU            menu_name4              This takes you to menu 4
VARIABLE        var_name3               Alter variable3
VARIABLE        var_name4       PRIV    Alter variable4
COMMAND         command3                Perform command3

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

Результатом в настоящее время является словарь, ключом которого является заголовок меню, а значением - другой словарь, содержащий пункты меню (значения, следующие за заголовком) следующим образом:

{'title1': {'1': 'menu_name1', '3': 'var_name1', '2': 'menu_name2', '5': 'command1', '4': 'var_name2'}}

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

Еще раз спасибо

Tom

Ответы [ 3 ]

2 голосов
/ 13 июля 2010

Если я правильно понимаю описание вашей проблемы, вы хотите повторить цикл body (в некоторых случаях), а не "итерацию".Если это так, один из подходящих подходов состоит в том, чтобы превратить тело цикла в возможно рекурсивную функцию, возвращая True, если цикл должен прерваться, False, если он будет продолжен, а также возможный заголовок.Например, наиболее прямая (хотя, вероятно, не максимально элегантная) функция:

def body(line):
    global title_flag

    # skip over comments
    if line[0] == '#':
        return None, False
    # skip over blank lines
    if re.search(r'^\s+$', line):
        return None, False

    # Find the line where the title is defined
    if 'DEFINE_MENU' in line and title_flag == 0:
        type, name = line.split()
        title = name
        title_flag = 1
        return title, body(line)

    # If DEFINE_MENU is found and flag has been raised, this
    # signifies a new menu definition.
    if 'DEFINE_MENU' in line and title_flag == 1:
        return None, True

и код основной линии становится:

title_flag = 0

with open('some_file', 'r') as afile:
    for line in afile:
        thetitle, mustbreak = body(line)
        if thetitle is not Note: title = thetitle
        if mustbreak: break

Кстати: do not присваивайте имена своим собственным переменным, узурпируя встроенные имена, такие как file - это отдельная тема ;-).Кстати: я использую with (предполагается Python 2.6 или выше, или 2.5 с «импортом из будущего») только потому, что это правильный способ открывать и закрывать файл ;-).Кстати, я удалил re.search, потому что это бессмысленное, необъяснимое излишество, когда простой оператор in явно выполняет ту же работу.

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

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

0 голосов
/ 13 июля 2010

Я не уверен, что именно вы ищете, но возможно ли будет просто сохранить ваши заголовки в списке?

titles = []

for line in infile: # don't shadow "file" keyword...

    if "DEFINE_MENU" in line:
        titles.append(line.split()[-1]) # append the last item

, если вы хотите только первые два заголовка, вы можете добавитьдополнительный тест:

if len(titles) == 2: break
0 голосов
/ 13 июля 2010

Отражает ли это вашу логику?

menus = []
current_menu = None
for line in file:
    # ...
    # Find the line where the title is defined
    if re.search('DEFINE_MENU', line):
        if not current_menu is None:
            menus.append(current_menu)
        current_menu = Menu()
        type, name = line.split()
        current_menu.setTitle(name)
        continue

Menu будет вспомогательным классом для хранения всей информации, которая принадлежит одному меню.Кроме того, поскольку все ваши дела кажутся взаимоисключающими, рассмотрите возможность использования elif вместо continue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...