8

Is there a pythonic way (I know I can loop using range(len(..)) and get an index) to do the following example:

for line in list_of_strings:
    if line[0] == '$':
        while line[-1] == '#':
            # read in the Next line and do stuff
        # after quitting out of the while loop, the next iteration of the for loop
        # should not get any of the lines that the while loop already dealt with

essentially, the nested while loop should be incrementing the for loop.

Edit: Not a file handle, confused two things I was working on, it's a list of strings

2
  • 3
    Use line.startswith and line.endswith instead of line[0] and line[-1]. It works well with empty lines. And also looks better :). Commented Jul 26, 2011 at 18:41
  • @utdemir: mind blown, i had been doing so many checks for len(line) > 0 Commented Jul 26, 2011 at 20:45

2 Answers 2

9

One of the most basic challenges in python is getting clever when iterating over lists and dicts. If you actually need to modify the collection while iterating, you may need to work on a copy, or store changes to apply at the end of iteration.

In your case, though, you just need to skip items in the list. You can probably manage this by expanding iteration into an more explicit form.

i = iter(list_of_strings)
for line in i:
    if line.startswith('$'):
        while line.endswith('#'):
            line = i.next()
        # do work on 'line' which begins with $ and doesn't end with #

and that's all you really need to do.

Edit: As kindall mentions, if the while portion may iterate past the end of the input sequence, you'll need to do a bit more. You can do the following.

i = iter(list_of_strings)
for line in i:
    if line[0] == '$':
        try:
            while line[-1] == '#':
                line = i.next()
        except StopIteration:
            break
        # do work on 'line' which begins with $ and doesn't end with #
Sign up to request clarification or add additional context in comments.

1 Comment

if i.next() raises StopIteration (because, say, the last line of the list ends with an octothorpe) it will not be caught by the for. You'll need to catch it separately.
5

As long as file is a file handle you can do this instead of using readlines():

for line in fh:
  if line[0] == '$':
    while line[-1] == '#':
      line = next(fh)

File handles are iterable, and the next() function retrieves the next value from an iterable.

3 Comments

ah sorry, mixed up two different problems, it's not a file handle
I think g.d.d.c still answers your question. use next() to adjust your iterator
the missing link is that if list_of_strings is iterable, then fh = iter(list_of_strings) is needed before the for loop. It happens that files are their own iterators, although lists are not.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.