Erzeugen von zyklischen Permutationen / reduzierte lateinische Quadrate in Python

7

Ich habe mich nur gefragt, wie man die zyklischen Permutationen einer Liste in Python am effizientesten erzeugen kann. In jede Richtung. Zum Beispiel möchte ich bei einer Liste [1, 2, 3, 4] entweder:

generieren %Vor%

wobei die nächste Permutation erzeugt wird, indem das letzte Element nach vorne verschoben wird, oder:

%Vor%

wobei die nächste Permutation durch Verschieben des ersten Elements nach hinten erzeugt wird.

Der zweite Fall ist etwas interessanter für mich, weil er zu einem reduzierten lateinischen Quadrat führt (der erste Fall gibt auch ein lateinisches Quadrat, nur nicht reduziert), was ich für experimentelles Blockdesign verwende. Es ist eigentlich nicht so anders als im ersten Fall, da sie sich nur gegenseitig neu ordnen, aber die Reihenfolge spielt immer noch eine Rolle.

Die aktuelle Implementierung, die ich für den ersten Fall habe, ist:

%Vor%

Für den zweiten Fall:

%Vor%

Der erste Fall scheint mir einigermaßen effizient zu sein, da er pop() verwendet, aber das kann man im zweiten Fall nicht tun, also würde ich gerne Ideen dazu hören, wie man das effizienter macht . Vielleicht gibt es etwas in itertools , das hilft? Oder vielleicht eine doppelendige Warteschlange für den zweiten Fall?

    
ztangent 15.03.2011, 15:21
quelle

7 Antworten

7

Für den ersten Teil ist der prägnanteste Weg wahrscheinlich

%Vor%

und für den zweiten Teil

%Vor%

Diese sollten auch viel effizienter als Ihr Code sein, obwohl ich keine Zeitsteuerungen vorgenommen habe.

    
Sven Marnach 15.03.2011, 15:26
quelle
15

Sie können collections.deque verwenden:

%Vor%

Es druckt:

%Vor%

Um es für die linke Rotation zu ändern, ersetzen Sie einfach g.rotate(1) durch g.rotate(-1) .

    
Maciej Ziarko 15.03.2011 15:26
quelle
1

Variation zum Schneiden "Erhaltungssatz" a = a[:i] + a[i:]

%Vor%     
f5r5e5d 13.02.2017 22:56
quelle
0

Verwenden von iertools, um Indexierung zu vermeiden:

%Vor%     
Bruno Lenzi 08.06.2012 07:12
quelle
0

Dies wird meine Lösung sein.

%Vor%

Dies wird Folgendes ausgeben:

%Vor%

Sie können auch pop verwenden, anstatt Listen-Slicing zu verwenden, aber das Problem mit pop ist, dass etwas zurückgegeben wird.

Auch der obige Code funktioniert für jede Länge der Liste. Ich habe die Leistung des Codes nicht überprüft. Ich gehe davon aus, dass es besser funktioniert.

Hoffe, das hilft. Wenn Sie irgendwelche Zweifel haben, können Sie Kontakt mit mir aufnehmen. Ich werde froh sein, Ihnen zu helfen.

>

Sie sollten sich Python-Dokumente ansehen, um ein gutes Verständnis für das List-Slicing zu erhalten.

    
Anivarth 15.05.2016 17:38
quelle
0

Die Antwort von @Bruno Lenzi scheint nicht zu funktionieren:

%Vor%

Ich gebe unten eine korrekte Version, aber die Lösung von @ f5r5e5d ist schneller.

%Vor%

Ich habe die Print-Anweisung in use_cycle und use_slice für Timing-Zwecke entfernt.

    
user2487951 16.02.2017 21:31
quelle
0

more_itertools ist eine Bibliothek eines Drittanbieters, die ein Tool für zyklische Permutationen :

%Vor%

Siehe auch Wikipedia :

  

Eine zirkulare Verschiebung ist eine spezielle Art von zyklischer Permutation, die wiederum eine spezielle Art von Permutation ist.

    
pylang 22.01.2018 06:57
quelle