2012-03-20 110 views
4

python中下面的等价物是什么?如何在Python中执行C++风格(索引)嵌套循环?

for (i=0; i<n; i++) 
    for (j=i+1; j<n; j++) 
     //do stuff with A[i], A[j] 

或者在某种意义上,以下。它也应该在循环的每一轮完成时从A中删除元素。

for a in A: 
    for a' in A/{a}: #i.e. rest of the elements of A 
     #do something with a,a' 
    #remove a from A 

有没有使用枚举()这样做的pythonic方法?

编辑:

对不起,这个不好的描述。

  1. 在第一个例子中,我的意思是只使用i & j作为索引。他们的价值观并不重要。它只是一个粗略的C++相当于后者。

  2. 外循环执行n次。对于外部循环的每次迭代,内部循环执行(n-1),(n-2)... 0次。

也许这可能帮助(伪):

function next_iteration(list): 
    head = first element 
    tail = remaining elements #list 
    each element in tail interacts with head one by one 
    next_iteration(tail) 

PS:以上所有的代码示例pseudocodes。我想表达的东西在我的脑海中仍然有点模糊。

+2

你的两个循环不会做同样的事情。选一个! – katrielalex 2012-03-20 13:31:13

+1

@katrielalex - 不明确,但概念上它们都可以代表相同序列上的嵌套循环,其中内部循环在外部循环中的当前元素之后立即开始。 – 2012-03-20 13:41:20

+0

第二个例子在开始时开始内循环,只跳过元素“a”。 – hochl 2012-03-20 13:46:44

回答

3

因为你的两个问题是不同的,这里是你的第二个问题的解决方案:

for i in xrange(len(A)): 
    for j in xrange(len(A)): 
     if i != j: 
      do_stuff(A[i], A[j]) 

使用itertools(我认为使用附带电池非常pythonic!):

import itertools 

for a, b in itertools.permutations(A, 2): 
    do_stuff(a, b) 

这适用于do_stuff我要存储结果从A 2个的不同元素的所有组合只需使用:

[do_stuff(a, b) for a, b in itertools.permutations(A, 2)] 
+0

嗨,几乎在那里。 :) 你能让它工作在(a,b)和(b,a)相同的方式吗?也就是说,顺序无关紧要。 – Karthick 2012-03-20 14:19:45

+0

我认为'itertools.combinations'会做的。 – hochl 2012-03-20 14:36:16

0

如何:

for i in range(0,n): 
    for j in range (i+1,n): 
    # do stuff 
0
for i in range(0,n): 
    for j in range(i+1,n): 
    # do stuff 
0

仍然不能发表评论。但基本上是其他两个帖子说 - 但养成使用xrange而不是范围的习惯。

for i in xrange(0,n): 
    for j in xrange(i+1,n): 
    # do stuff 
+0

'range()'在python 3中返回生成器。x – rplnt 2012-03-20 13:41:38

+0

它确实,但是op从未指定版本,所以我倾向于假设<3.x:] – headcrab 2012-03-20 13:44:46

+0

随着2.x的出路和3.x的方式,最好养成使用' range'。 – 2012-03-20 22:01:01

0

可以使用xrange为i和j值生成分别如下显示:

for i in xrange(0, n): 
    for j in xrange(i + 1, n): 
     # do stuff 
0

你可以使内环直接放在切片。并不是说这更好,但它是另一种方法。

for i in range(0,len(x)): 
    a = x[i] 
    for b in x[i+1:]: 
    print a, b 
0

另一种方式来处理,这是 - 如果ñ是提供迭代器接口的顺序,那么在Python中,你可以通过遍历直接在物体简化代码:

for i in n: 
    for some_var in n[n.index(i):]: # rest of items 
    # do something 

我希望我正确理解你的循环,因为正如其他人所说 - 他们不会做同样的事情。

4

我解读您要问的是

我怎么能遍历所有对容器的不同元素?

答:

>>> x = {1,2,3} 
>>> import itertools 
>>> for a, b in itertools.permutations(x, 2): 
...  print a, b 
... 
1 2 
1 3 
2 1 
2 3 
3 1 
3 2 

编辑:如果你不希望同时(a,b)(b,a),只需使用itertools.combinations代替。

+0

所有成对的不同元素,不考虑每对中元素的顺序。这种改变如何适应这种情况? – Karthick 2012-03-20 14:21:09

+1

@Karthick使用'.combinations'代替。请参阅[文档](http://docs.python.org/library/itertools.html#itertools.combinations)。 – katrielalex 2012-03-20 16:02:46

0

对于您的问题,第一个是,正如其他的答案中提到:

for i in xrange(n): 
    for j in xrange(i+1, n): 
     # do stuff with A[i] and A[j] 

对于第二个:

for i, a in enumerate(A): 
    for b in A[i+1:]: 
     # do stuff with a and b 
0

你的伪代码几乎都有它:

function next_iteration(list): 
    head = first element 
    tail = remaining elements #list 
    each element in tail interacts with head one by one 
    next_iteration(tail) 

Python代码:

def next_iteration(lst): 
    head, tail = lst[0], lst[1:] 
    for item in tail: 
     print(head, item) 
    if tail: 
     next_iteration(tail) 

,当与next_iteration([1, 2, 3]),印刷品尝试:

1 2 
1 3 
2 3 
0

在第一for循环中,枚举()遍历阵列并且使索引,每个元件的值提供给所述第二for循环。在第二个循环中,范围()使得j = i + 1→len(a)可用。在这一点上,你会有你需要的是i & j做你的操作。

>>> a = [1,2,3,4] 
>>> array_len = len(a) 
>>> for i,v in enumerate(a): 
... for j in range(i+1, array_len): 
...  print a[i], a[j] 
... 
1 2 
1 3 
1 4 
2 3 
2 4 
3 4 
>>>