2017-01-24 5 views
0

Ich versuche, alle Permutationen für eine bestimmte Menge zu generieren. Bei jedem Rückruf meines Codes ändert sich der Inhalt des Arrays aus irgendeinem Grund, wenn ich die Append-Funktion verwende. Kann mir jemand in die richtige Richtung zeigen?Warum mutiert mein Code den Inhalt einer Liste in Python?

class Solution(object): 
    def permute(self, nums): 
     res = [] 
     self.generate_permutations(nums, res, 0, len(nums)-1) 
     return res 

    def generate_permutations(self, nums, res, l, r): 
     if l == r: 
      res.append(nums) 

     for i in range(l, r+1): 
      nums[i], nums[l] = nums[l], nums[i] 
      print('res', res) 
      self.generate_permutations(nums, res, l+1, r) 
      nums[l], nums[i] = nums[i], nums[l] 
+0

By the way, 'Rückkehr res.append'' None' zurückkehren wird und Sie nie die rekursive Rückgabewert erfassen, aber 'itertools' dein Freund ist, und Sie sollten Lernen Sie diese Methode, Permutationen zu machen –

+1

Listen werden als Referenz übergeben. –

+0

@ cricket_007 keine ahnung, warum ich zurück res.append da drin hatte. Aber ich benutze itertools nicht, weil dies für algorthm Studie ist. Es erzeugt die Permutationen korrekt, aber es gibt einen Python, der die Werte verändert – driftdrift

Antwort

1

Vielleicht vereinfacht Generator wird das Problem deutlicher machen:

def gen(num): 
    for i in range(3): 
     num.append(i) 
     yield num 

Es erzeugt eine wachsende Liste:

In [119]: g=gen([]) 
In [121]: next(g) 
Out[121]: [0] 
In [122]: next(g) 
Out[122]: [0, 1] 
In [123]: next(g) 
Out[123]: [0, 1, 2] 

Aber wenn ich die Ergebnisse in einer Liste sammeln, ich Wiederholungen erhalten

In [125]: [i for i in gen([])] 
Out[125]: [[0, 1, 2], [0, 1, 2], [0, 1, 2]] 

Stattdessen muss ich Kopien sammeln

In [126]: [i[:] for i in gen([])] 
Out[126]: [[0], [0, 1], [0, 1, 2]] 

Die Wiederholungen offensichtlicher sein, wenn ich an der id jedes Elements aussehen

In [129]: [id(i) for i in alist] 
Out[129]: [2881121580, 2881121580, 2881121580] 

oder wenn ich ein Element der Liste ändern (und am Ende Modifizieren alle)

In [130]: alist[0].append(10) 
In [131]: alist 
Out[131]: [[0, 1, 2, 10], [0, 1, 2, 10], [0, 1, 2, 10]] 

=================

Mit Ihrem f Salbung, Speichern nums[:]-res:

def generate_permutations(nums, res, l, r): 
     if l == r: 
      res.append(nums[:])  # <=== change 
     for i in range(l, r+1): 
      nums[i], nums[l] = nums[l], nums[i] 
      generate_permutations(nums, res, l+1, r) 
      nums[l], nums[i] = nums[i], nums[l] 
In [158]: res=[];nums=[1,2,3] 
In [159]: generate_permutations(nums, res,0,2) 
In [160]: res 
Out[160]: [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2]] 
Verwandte Themen