se demandait simplement quelle est la manière la plus efficace de générer tous les changements circulaires d'une liste en python. Dans les deux sens. Par exemple, étant donné une liste où la prochaine permutation est générée en déplaçant le dernier élément à l'avant, ou: p> où la prochaine permutation est générée en déplaçant le premier élément à l'arrière. p> Le second cas est légèrement plus Intéressant pour moi, car il entraîne une place latine réduite (le premier cas donne également un carré latin, tout simplement pas réduit), ce que j'essaie d'utiliser pour faire la conception de bloc expérimentale. En réalité, ce n'est pas si différent du premier cas, car ils ne sont que des réchrographies les uns des autres, mais l'ordre est toujours important. P> La mise en œuvre actuelle que j'ai pour le premier cas est la suivante: P > pour le second cas: p> Le premier cas semble être raisonnablement efficace pour moi, car il utilise < CODE> POP () CODE>, mais vous ne pouvez pas faire cela dans le second cas, j'aimerais donc entendre des idées sur la manière de le faire plus efficacement. Peut-être qu'il y a quelque chose dans [1, 2, 3, 4] code>, je veux générer:
itTools code> qui aidera? Ou peut-être une file d'attente à double extrémité pour le second cas? P> p>
7 Réponses :
Pour la première partie, la manière la plus concise est probablement et pour la deuxième partie p> celles-ci devraient également être beaucoup plus efficace que votre code, bien que je n'ai pas fait de timings. p> p>
Wow, ne pensais pas que vous pourriez faire cela en utilisant des compréhensions de la liste! J'aurais peut-être dû penser plus fort. Les accessoires de ne pas avoir à utiliser de modules supplémentaires.
Vous pouvez utiliser collections.deque: IT imprime: p> pour le changer pour la rotation gauche, remplacez simplement g.rotate (1) code> avec
g.rotate (-1) code>. p> p>
Cette méthode rotation code> est assez cool. Je ne savais jamais que desquelles pouvaient faire ça. Là encore, j'ai probablement lu la documentation à fond avant de demander.
Comme il s'agit de la file d'attente double extrémité, rotation code> est probablement implémenté efficacement.
Et les documentations sont en effet nos meilleurs amis. :)
Utilisation d'iTerTools pour éviter l'indexation:
x = itertools.cycle(a) [[x.next() for i in a] for j in a]
Ce sera ma solution.
[4, 1, 2, 3] [3, 4, 1, 2] [2, 3, 4, 1] [1, 2, 3, 4]
Variation de la "Droit de la conservation" A = A [: I] + A [I:] CODE>
ns = list(range(5))
ns
Out[34]: [0, 1, 2, 3, 4]
[ns[i:] + ns[:i] for i in range(len(ns))]
Out[36]:
[[0, 1, 2, 3, 4],
[1, 2, 3, 4, 0],
[2, 3, 4, 0, 1],
[3, 4, 0, 1, 2],
[4, 0, 1, 2, 3]]
[ns[-i:] + ns[:-i] for i in range(len(ns))]
Out[38]:
[[0, 1, 2, 3, 4],
[4, 0, 1, 2, 3],
[3, 4, 0, 1, 2],
[2, 3, 4, 0, 1],
[1, 2, 3, 4, 0]]
La réponse de @bruno Lenzi ne semble pas fonctionner: i Donnez une version correcte ci-dessous, mais la solution de @ F5R5E5D est plus rapide. P> In [45]: def use_cycle(a):
x=cycle(a)
for _ in a:
x.next()
print [x.next() for _ in a]
....:
In [46]: use_cycle([1,2,3,4])
[2, 3, 4, 1]
[3, 4, 1, 2]
[4, 1, 2, 3]
[1, 2, 3, 4]
In [50]: def use_slice(a):
print [ a[n:] + a[:n] for n in range(len(a)) ]
....:
In [51]: use_slice([1,2,3,4])
[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]
In [54]: timeit.timeit('use_cycle([1,2,3,4])','from __main__ import use_cycle',number=100000)
Out[54]: 0.4884989261627197
In [55]: timeit.timeit('use_slice([1,2,3,4])','from __main__ import use_slice',number=100000)
Out[55]: 0.3103291988372803
In [58]: timeit.timeit('use_cycle([1,2,3,4]*100)','from __main__ import use_cycle',number=100)
Out[58]: 2.4427831172943115
In [59]: timeit.timeit('use_slice([1,2,3,4]*100)','from __main__ import use_slice',number=100)
Out[59]: 0.12029695510864258
more_itertools code>
est une bibliothèque tierce qui offre un outil pour Permutations cycliques :
import more_itertools as mit mit.circular_shifts(range(1, 5)) # [(1, 2, 3, 4), (2, 3, 4, 1), (3, 4, 1, 2), (4, 1, 2, 3)]
Votre implémentation ne fonctionne pas - ils ajoutent une liste (INTS) et des listes, ce qui est impossible. En outre, ils sont ajoutés à la même instance de liste dans chaque itération. Vous allez donc vous retrouver avec un carré composé de N fois la même ligne.
Whoops, a raté cela, merci. N'a pas réellement testé le code: p