views:

219

answers:

9

Can I do something like this in Python?

for (i = 0; i < 10; i++):
  if someCondition:
     i+=1
  print i

I need to be able to skip some values based on a condition

EDIT: All the solutions so far suggest pruning the initial range in one way or another, based on an already known condition. This is not useful for me, so let me explain what I want to do.

I want to manually (i.e. no getopt) parse some cmd line args, where each 'keyword' has a certain number of parameters, something like this:

for i in range(0,len(argv)):
    arg = argv[i]
    if arg == '--flag1':
       opt1 = argv[i+1]
       i+=1
       continue
    if arg == '--anotherFlag':
       optX = argv[i+1]
       optY = argv[i+2]
       optZ = argv[i+3]
       i+=3
       continue

    ...
+10  A: 

Yes, this is how I would do it

>>> for i in xrange(0, 10):
...     if i == 4:
...         continue
...     print i,
...
0 1 2 3 5 6 7 8 9

EDIT
Based on the update to your original question... I would suggest you take a look at optparse

sberry2A
You mean yes :)
Charles Beattie
The printout should be "0 1 2 3 5 6 7 8 9"
che
@che: Yeah, already fixed that... got fat fingers in the morning sometimes.
sberry2A
+1 for `optparse`. Parsing command-line arguments manually is completely unnecessary.
Justin Ardini
Apparently optparse is obsoleted in 2.7, and the new flavor is called argparse. They both seem to be able to do what I need, but I'm wondering if it's worth the learning curve. Anyway, +1 for pointing out this module.
Cristi Diaconescu
+1  A: 

You should use continue to skip a value, in both C and Python.

for i in range(10):
  if someCondition:
     continue
  print(i)
KennyTM
A break won't skip the value though... it will break out of the for loop. Wouldn't you want a `continue`?
sberry2A
@sberry: Yes... What was I thinking :p
KennyTM
+3  A: 

Strange way:

for x in (x for x in xrange(10) if someCondition):
    print str(x)
Charles Beattie
+2  A: 

You probably don't actually need the indices, you probably need the actual items. A better solution would probably be like this:

sequence = 'whatever'
for item in sequence:
    if some_condition:
        continue
    do_stuff_with(item)
Christian Oudard
I would dearly use an iterator over a for loop any time of the day, however I can't think of a way to use iteration in my situation - see updated question
Cristi Diaconescu
A: 
 for i in xrange(0, 10):
    if i % 3 == 0
        continue
    print i

Will only values which aren't divisible by 3.

Teodor Pripoae
+3  A: 

There are two things you could do to solve your problem:

  • require comma-separated arguments which are going to be grouped into the following option value, you could use getopt, or any other module then.
  • or do more fragile own processing:

    sys.argv.pop()
    cmd = {}
    while sys.argv:
        arg = sys.argv.pop(0)
        if arg == '--arg1':
            cmd[arg] = sys.argv.pop(0), sys.argv.pop(0)
        elif:
            pass
    print(cmd)
    
SilentGhost
The idea of using argv as a stack is great for my needs, and it removes the indexed based access to the list.
Cristi Diaconescu
A: 

If you need to iterate over something, and need an index, use enumerate()

for i, arg in enumerate(argv):
    ...

which does the same as the questioner's

for i in range(0,len(argv)):
    arg = argv[i]
catchmeifyoutry
A: 

Your problem seems to be that you should loop not raw parameters but parsed parameters. I would suggest you to consider to change your decision not to use standard module (like the others).

Tony Veijalainen
+1  A: 

You could first turn the argv list into a generator:

def g(my_list):
    for item in my_list:
        yield item

You could then step through the items, invoking the generator as required:

my_gen = g(sys.argv[1:]):
while True:
   try:
      arg = my_gen.next()
      if arg == "--flag1":
         optX = my_gen.next()
         opyY = my_gen.next()
         --do something
      elif arg == "--flag2":
         optX = my_gen.next()
         optY = my_gen.next()
         optZ = my_gen.next()
         --do something else
      ...
    except StopIteration:
       break
Larry
how's that any different than iterating over a list? just more hassle.
SilentGhost
The idea is good, but why convert `sys.argv[1:]` to a generator instance rather than an iterator? E.g. `my_gen = iter(sys.argv[1:])` will get you the same results as your function `g`.
Muhammad Alkarouri
Also, instead of using `while` with `try: except StopIteration:` a for loop will achieve the same thing. Simply: `for arg in my_gen`. You can still use `my_gen.next()` in the loop.
Muhammad Alkarouri