Is it possible to repeat an iteration of a loop?
I have defined a for loop as follows which scans through a file made up of two columns, when it finds the keyword DEFINE_MENU
the second column on this line refers to the title for a screen. The next instance of the keyword will define a title for a seperate screen and so on to the nth screen. At the moment the code is capable of defining the first menu title.
Is it possible, when I reach the second instance of the keyword DEFINE_MENU
to repeat the loop for the same line, setting the title_flag = 0
thereby repeating itself, capturing the second menu title?
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
Thank you for your input!
Tom
EDIT: First, apologies for the confusion caused. Perhaps I thought of the problem as being simpler than I thought and gave less information than required. I will delve deeper, the input file i am using is of the form:
# 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
I had raised the flag as I further manipulate the data between the DEFINE_MENU
calls. I have edited the code to include the full method that I have written.
The outcome is currently a dictionary where the key is the menu title and value is the another dictionary containing the menu items (values following the title) as follows:
{'title1': {'1': 'menu_name1', '3': 'var_name1', '2': 'menu_name2', '5': 'command1', '4': 'var_name2'}}
What I would like to have is a larger dictionary containing the menu titles as keys with the lowest level dictionary as the value. I understand that this is complicated so I'm sorry if it unclear, let me know if more information is required.
Thanks again
Tom
If I understand your problem description correctly, you want to repeat the loop body (in certain cases) rather than "the iteration". If that's the case, one workable approach is to make the loop body into a possibly-recursive function, returning True
if the loop is to break, False
if it is to continue, as well as the possible title. For example, a most-direct (though probably not maximally elegant) function:
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
and the main-line code becomes:
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
BTW: do not name your own variables by usurping built-in names like file
-- that's a separate subject;-). BTW2: I'm using with
(assuming Python 2.6 or better, or 2.5 with an "import from the future") only because it's the right way to open and close a file;-). BTW3: I removed the re.search
because it's wanton, inexplicable overkill when a simple in
operator clearly does the same job.
I'm posting this code mostly to check in a concrete way whether I understood your specs, because, behavior-wise, this is definitely overkill -- there's no need (from the code you posted) to repeat the checks for comments and empty lines, nor the search for 'DEFINE_MENU"
, etc... you could just exit as soon as you've set the title (and body
could then become inline code again).
But, I imagine that you have a reason for posting your question, i.e., that the simple behavior this has (and which could be had much more simply) is not optimal for you -- maybe by seeing the solution to your literal question you can point out what you want different than this, and then we can actually help you;-).
Does this somewhat capture your logic?
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
would be a helper class for storing all the information that belongs to one menu. Also, since it seems all your cases are mutually exclusive, consider using elif
instead of continue
.
I'm not sure exactly what you're after, but would it be possible to just store your titles in a list?
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 you only want the first two titles, you could add an extra test:
if len(titles) == 2: break
精彩评论