Python:是否有类似于C语言的for循环可用?

20

我能在Python中做类似这样的事情吗?

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

我需要能够根据条件跳过一些值。

编辑:到目前为止,所有的解决方案都建议根据已知条件在某种程度上修剪初始范围。这对我没有用,所以让我解释一下我想做什么。

我想手动(即不使用 getopt)解析一些命令行参数,其中每个“关键字”具有一定数量的参数,类似于以下内容:

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

    ...

2
你实际上想要做什么? - SilentGhost
更新了更多信息的问题... - Cristian Diaconescu
1
永远有 while 等着你。 - Constantin
12个回答

24

是的,这就是我会做的方法

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

编辑
根据您最初问题的更新... 我建议您查看optparse


2
+1 for optparse。手动解析命令行参数是完全不必要的。 - Justin Ardini
3
显然,optparse在2.7版本中已经过时,新的替代品叫做argparse。 它们都似乎能够满足我的需求,但我想知道学习曲线是否值得。无论如何,感谢指出这个模块。 - Cristian Diaconescu

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

在Python中,它将被写作

i = 0
while i < 10
   if someCondition
      i += 1
   print i
   i += 1

搞定了,这就是如何在Python中编写一个C语言风格的循环。


4
@Cristi 是的,但那是问题中的原始示例代码,所以我认为那就是他想要的。 - Netzsooc

8
有两件事情可以解决你的问题:
  • 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)
    

将argv用作堆栈的想法非常适合我的需求,它还消除了对列表的基于索引的访问。 - Cristian Diaconescu
1
我喜欢当别人对问题提出各种建议,却没有给出答案。 - impulsgraw

5

奇怪的方式:

for x in (x for x in xrange(10) if someCondition):
    print str(x)

3

在C和Python中,应该使用continue来跳过一个值。

for i in range(10):
  if someCondition:
     continue
  print(i)

2

你可能实际上并不需要索引,而是需要实际的项。更好的解决方案可能是这样的:

sequence = 'whatever'
for item in sequence:
    if some_condition:
        continue
    do_stuff_with(item)

无论何时,我都更愿意使用迭代器而不是for循环,但是我想不出在我的情况下如何使用迭代 - 请参见更新的问题。 - Cristian Diaconescu

1
您可以先将 argv 列表转换为生成器:
def g(my_list):
    for item in my_list:
        yield item

您可以通过逐个迭代这些项目,并根据需要调用生成器来实现:
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

这有什么不同于遍历列表?只是更麻烦。 - SilentGhost
这个想法很好,但为什么要将 sys.argv[1:] 转换为生成器实例而不是迭代器呢?例如,my_gen = iter(sys.argv[1:]) 将会得到与您的函数 g 相同的结果。 - Muhammad Alkarouri
另外,与其使用 whiletry: except StopIteration:,使用 for 循环可以达到同样的效果。简单地说:for arg in my_gen。你仍然可以在循环中使用 my_gen.next() - Muhammad Alkarouri

0

您可以确保在try...finally块内递增索引。这解决了想要在不必复制/粘贴i += 1的情况下继续到下一个索引的常见问题。这是类似C语言的for循环提供的主要优势之一。

使用try...finally的主要缺点是需要再次缩进代码。但如果您有一个带有许多continue条件的while循环,那么这可能是值得的。

示例

此示例演示了即使调用了continuei仍会在finally块中递增。如果不递增i,则其值将永远保持不变,while循环将变为无限循环。

i = 0
while i < 10:
    try:
        print(i)

        if i % 2 == 0:
            continue

    finally:
        i += 1

如果没有它,你就必须在调用continue之前递增i

i = 0
while i < 10:
    print(i)

    if i % 2 == 0:
        i += 1 # duplicate code
        continue

    i += 1

-1
 for i in xrange(0, 10):
    if i % 3 == 0
        continue
    print i

只返回不能被3整除的值。


-1

如果你需要遍历某个东西,并且需要一个索引,可以使用enumerate()

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

这与提问者的代码执行相同

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接