2017-01-23 3 views
-1

Я хочу создать функцию для каждой возможной перестановки массива. Я написал код, и я не знаю, что с ним не так. Он возвращает мне первую возможность = [1,2,3], но затем он терпит неудачу с ошибкой: оригинал [i] из индекса, но он должен быть оригинальным [1], который равен 2. Возможно, tem temp также стирается от оригинала, но это будет не имеет смысла для меня.Перестановка в Python - шаблон

Благодарим вас в advace.

array = [1,2,3] 
out = [] 

def permutacja(original,perm): 
    if(len(original) == 0): 
     print(perm) 
     return perm 

    temp = original 
    for i in range(0,len(original)): 
     perm.append(original[i]) 
     del temp[0] 
     permutacja(temp,perm) 
     del perm[len(perm)-1] 

permutacja(array,out) 
+0

да, температура стирает также из оригинального 'TMP = массив #copies ссылки на list' insdead вы должны использовать: 'tmp = list (array)' –

ответ

4

модуль стандартной библиотеки Python itertools обеспечивают itertools.permutations что дает перестановкам:

>>> import itertools 
>>> for xs in itertools.permutations([1,2,3]): 
...  print(xs) 
... 
(1, 2, 3) 
(1, 3, 2) 
(2, 1, 3) 
(2, 3, 1) 
(3, 1, 2) 
(3, 2, 1) 
+0

спасибо, но мне нужно это для более сложного алгоритма, который включает в себя разные типы данных, мне нужно понять простой способ сделать это, чтобы вложить это в мой алгоритм – user3541098

+1

@ user3541098, Okay , Я дам вам подсказку о вашем импе проблема лекций. Выполняя 'temp = original',' temp' ссылается на тот же список (не копируя). Сделав 'temp = original [:]', вы получите копию. – falsetru

+0

@ user3541098: 'itertools' работает со всеми видами данных: строками, ints, float, objects и т. Д. –

0

Лучше использовать itertools для этого, так как они хорошо оптимизированы и протестированы процедуры. Тем не менее в случае, если вы хотите реализовать его самостоятельно, есть некоторые вещи, которые могут быть улучшены/исправлены:

  • Вам return значение, но только в последнем шаге рекурсии вы должны распространять их обратно;
  • Вы возвращаете ссылку в список, который вы строите на лету, в результате вы всегда будете возвращать тот же список;
  • Вы всегда del ete первый элемент, а не тот, который вы выбрали; и
  • Вы делаете не восстанавливается элемент после удаления.
def permutacja(original,perm): 
    if(len(original) == 0): 
     print(perm) 
     yield perm.copy() # emit instead of return for proagation 
    else: 
     temp = original 
     for i in range(0,len(original)): 
      perm.append(original[i]) 
      temp = original[:i]+original[i+1:] #remove the i-th 
      for result in permutacja(temp,perm): 
       yield result # propagate back 
      del perm[len(perm)-1] 
      # because we copy original, no need to restore 

Некоторые улучшения: вывода дополнительных

  • использовать .pop() вместо del на последнем элементе; и
  • вы можете просто использовать if original вместо сравнения на len(..):
def permutacja(original,perm): 
    if original: 
     print(perm) 
     yield perm.copy() 
    else: 
     temp = original 
     for i in range(0,len(original)): 
      perm.append(original[i]) 
      temp = original[:i]+original[i+1:] #remove the i-th 
      for result in permutacja(temp,perm): 
       yield result # propagate back 
      perm.pop() 
      # because we copy original, no need to restore 
Смежные вопросы