it-swarm.com.de

Python Simple Swap-Funktion

Ich bin auf dieses Problem gestoßen, als ich versuchte, Python zu lernen. Betrachten Sie die folgende Funktion:

def swap0(s1, s2):
    assert type(s1) == list and type(s2) == list
    tmp = s1[:]
    s1 = s2[:]
    s2 = tmp
return

s1 = [1]
s2 = [2]
swap0(s1, s2)
print s1, s2

Was werden s1 und s2 gedruckt?

Nachdem ich das Problem ausgeführt hatte, stellte ich fest, dass die print-Anweisung 1 2 drucken wird. Der Wert von s1 und s2 hat sich anscheinend nicht von der swap0-Funktion geändert. Die einzige Erklärung, die mir einfiel, war die Linie.

tmp = s1[:]

Da es sich bei s1 [:] um eine Kopie handelt, ist es sinnvoll, dass sich der Wert von s1 im Funktionsaufruf nicht ändert. Da der Parameter von swap0 jedoch (s1, s2) ist, bin ich nicht sicher, ob nach dem Ausführen von tmp = s1 [:]. Ich kann es jederzeit tun

s1 = something...

es wird ein Verweis auf die Kopie von s1 anstelle von s1 selbst sein. Kann jemand eine bessere Erklärung anbieten? Vielen Dank.

10
Rhs

Dies liegt daran, dass s1 und s2 innerhalb der swap0-Funktion neue Werte zugewiesen werden. Diese Zuweisungen werden nicht außerhalb der Funktion propagiert. Sie werden feststellen, dass dies funktioniert, wenn Sie den Funktionskörper einfach an die Stelle des Funktionsaufrufs kopieren und einfügen.

Sie können dies umgehen, indem Sie die Objekte ändern, auf die die Argumente verweisen, und nicht die Argumente selbst:

def swap0(s1, s2):
    assert type(s1) == list and type(s2) == list
    tmp = s1[:]
    s1[:] = s2
    s2[:] = tmp

Der einfachere und bessere Weg, einen Python-Swap durchzuführen, ist jedoch einfach:

s1, s2 = s2, s1

Auch dies wird nur die einzelnen Verweise auf die Listen vertauschen, nicht jedoch den Listeninhalt selbst.

22
Thomas

Die endgültige print gibt die ursprünglichen Werte von s1 und s2 aus. Dies liegt daran, dass Sie sie nur im Rahmen der Funktion austauschen. Dies wirkt sich nicht auf ihre Werte außerhalb der Funktion aus (d. H. Nach dem Aufrufen der Funktion nach dem Aufruf der Funktion).

Wenn es sich um veränderliche Typen handelt (list, set, dict usw.), können Sie sie direkt in swap ändern. Dies beschränkt swap jedoch nur für veränderliche Typen.

Es ist daher besser, die Eingaben in umgekehrter Reihenfolge zurückzugeben:

def swap(s1, s2):
    return s2, s1

s1 = 'a'
s2 = 'b'
s1, s2 = swap(s1, s2)
print s1, s2 # prints 'b a'

Natürlich können Sie dies alles in einer Zeile wie folgt tun:

s1, s2 = s2, s1

Prost!

11
inspectorG4dget

Die anderen Antworten erklären, was schief läuft. Hier ist eine Version, die macht, was Sie wollen:

def swap(s1, s2):
    assert isinstance(s1, list) and isinstance(s2, list)
    s1[:], s2[:] = s2[:], s1[:]

Siehe auch: isinstance vs. type

6
Zero Piraeus

Innerhalb der Funktion binden Sie local variables s1 und s2 mit den Werten auf der rechten Seite (die auch lokal sind, da Sie zur Erstellung von Kopien Slices verwenden). Selbst wenn Sie den Inhalt dieser lokalen Variablen ändern, ändern Sie den Inhalt der Listen im aufrufenden Bereich nicht, da sie sich nicht mehr auf dieselben Listen beziehen.

4
mgilson

Hier ist eine einzeilige Funktion, die Ihr Ziel erreicht:

swap = lambda x: (x[1], x[0])
2
parallelogram

Sie können dies auch tun, indem Sie die alte Auslagerungsmethode mithilfe von Indexierung und Schleife verwenden, wenn beide Listen die gleiche Länge haben. Dies ist eine Art alte Schule, aber es hilft, die Indexierung zu verstehen 

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
b = [0, 9, 8, 7, 6, 5, 4, 3, 2, 1]

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

print(a)
print(b)

Dies gibt die Ausgabe als:

 [0,9,8,7,6,5,4,3,2,1]
 [1,2,3,4,5,6,7,8,9,0]

Oder es kann auch mit Xor gemacht werden. Der Operator Xor ist ein bitweiser Operator, der beispielsweise die Xor-Operation zwischen den Operanden ausführt.

a = 5 #0b101
b = 4 #0b100
c = a ^ b #0b001

Hier ist 0b101 eine binäre Repräsentation von 5 und 0b100 ist eine binäre Repräsentation von 4 und wenn Sie Xor oder Xor verwenden, werden Sie als 0b001 die Ausgabe erhalten. Xor gibt 1 Ausgangsergebnisse zurück, wenn einer und nur einer der Eingänge bis 1 ist. Wenn beide Eingänge 0 sind oder beide 1 sind, gibt 0 Ausgangsergebnisse aus .. _. Wir können zwei Variablen mit Xor austauschen, zB:

a = 5        # 0b0101
b = 9        # 0b1001
a = a ^ b    # Xor (0b0101, 0b1001) = 0b1100 (12)
b = a ^ b    # Xor (0b1100, 0b1001) = 0b0101 (5)
a = a ^ b    # Xor (0b1100, 0b0101) = 0b1001 (9)
print("a = {} and b = {}".format(a, b))

Die Ausgabe wird a = 9 and b = 5 sein. 

In ähnlicher Weise können wir auch zwei Listen austauschen, indem Sie die Xor-Operation für die folgenden Elemente ausführen, z.

a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ]
b = [ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 ] 

for i in range(0, len(a)) :
     a[i] = a[i] ^ b[i] 
     b[i] = a[i] ^ b[i] 
     a[i] = a[i] ^ b[i] 

print(a)
print(b)

Ausgabe:

[0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]

Nehmen wir ein anderes Szenario: Was ist, wenn wir die Elemente in der Liste gegen Folgendes austauschen müssen: Wir haben eine Liste wie x = [ 13, 3, 7, 5, 11, 1 ] und wir müssen das Element wie folgt x = [ 1, 3, 5, 7 , 11, 13 ] austauschen ^ und Komplimente ~ 

Code:

# List of items 
a = [ 13, 3, 7, 5, 11, 1 ]

# Calculated the length of list using len() and
# then calulated the middle index of that list a 

half = len(a) // 2

# Loop from 0 to middle index
for i in range(0, half) :

# This is to prevent index 1 and index 4 values to get swap 
# because they are in their right place.
if (i+1) % 2 is not 0 :

    #Here ~i means the compliment of i and ^ is Xor,
    # if i = 0 then ~i will be -1 
    # As we know -ve values index the list from right to left 
    # so a [-1] = 1 

    a[i] = a[i] ^ a[~i] 
    a[~i] = a[i] ^ a[~i] 
    a[i] = a[i] ^ a[~i]

print(a)

Die Ausgabe wird also [1, 3, 5, 7, 11, 13] sein.

2
Devil-oper

sie können dies haben:

def swap(x , y):
  x , y = y , x
  return x , y

x  = 5
y = 10

print ('x is {0} and y is {1}'.format(x,y))    # x is 5 and y is 10
x , y = swap(x,y)                              # doing swap 
print ('x is {0} and y is {1}'.format(x,y))    # x is 10 and y is 5
1
a_m_dev