Как сделать вложенные циклы в стиле C ++ (проиндексированные) в python? - PullRequest
4 голосов
/ 20 марта 2012

Что эквивалентно следующему в python?

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

Есть ли питонический способ сделать это без использования enumerate ()?

Редактировать:

Извините за плохое описание.

  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: Все приведенные выше примеры кода являются псевдокодами.Я пытаюсь выразить что-то немного смутное в моем уме.

Ответы [ 11 ]

4 голосов
/ 20 марта 2012

Я понимаю, что вы спрашиваете, как

Как я могу перебрать все пары отдельных элементов контейнера?

Ответ:

>>> 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 вместо.

3 голосов
/ 20 марта 2012

Поскольку ваши два вопроса различны, вот решение для вашей второй проблемы:

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

или с использованием itertools (я думаю, используя входящие в комплект батареи очень питонично!):

import itertools

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

Это применяет do_stuff ко всем комбинациям 2 различных элементов из A. Если вы хотите сохранить результат, просто используйте:

[do_stuff(a, b) for a, b in itertools.permutations(A, 2)]
0 голосов
/ 06 сентября 2014

В первом цикле for enumerate () проходит по массиву и делает индекс, значение каждого элемента доступным для второго цикла for. Во втором цикле range () делает доступным 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
>>>
0 голосов
/ 21 марта 2012

Ваш psuedocode почти имеет его:

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 голосов
/ 20 марта 2012

По первому из ваших вопросов, как уже упоминалось в других ответах:

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 голосов
/ 20 марта 2012

Другой способ подойти к этому - если n - это последовательность, которая обеспечивает итерируемый интерфейс, то в Python вы можете упростить свой код, перебирая объект напрямую:

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

Надеюсь, я правильно понял ваш цикл, потому что, как говорили другие, они не делают то же самое.

0 голосов
/ 20 марта 2012

Вы можете сделать внутренний цикл прямо над срезом.Не сказать, что это лучше, но это другой подход.

for i in range(0,len(x)):
  a = x[i]
  for b in x[i+1:]:
    print a, b
0 голосов
/ 20 марта 2012

Вы можете использовать xrange для генерации значений для i и j соответственно, как показано ниже:

for i in xrange(0, n):
   for j in xrange(i + 1, n):
       # do stuff
0 голосов
/ 20 марта 2012

Все еще не могу оставлять комментарии ... но в основном то, о чем говорили другие два поста, - но привычка использовать xrange вместо range.

for i in xrange(0,n):
   for j in xrange(i+1,n):
   # do stuff
0 голосов
/ 20 марта 2012
for i in range(0,n):
   for j in range(i+1,n):
   # do stuff
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...