2016-05-13 7 views
0

Ich weiß, dass es itertools.product For-Schleifen gibt, aber ich wollte etwas schreiben, das eine beliebige Koordinate in n-Raum mit der Iterationszahl zurückgibt, die es ergeben würde in einer Schleife. Ich habe bereits etwas geschrieben, das ähnlich ist, nämlich.Zuordnung einer bestimmten Iterationsnummer zu einer n-dimensionalen Liste/Array

def clock(iteration_number, axis_lengths): 
    dimension=len(axis_lengths) 
    coordinate = [] 
    for i in range(dimension): 
     s = axis_lengths[dimension-i-1:dimension-i][0] 
     g = iteration_number % s 
     iteration_number /= s 
     coordinate += [g] 
    return tuple(reversed(coordinate)) 

aber ich hoffe, dass mit Hilfe der eingebauten Funktion divmod (oder einem anderen), um eine Liste Verständnis komprimiert werden kann; Ich habe versucht, lambda Funktionen und map auch zu verwenden, aber ohne Erfolg, also bin ich fest. Beispielsweise führt das Ausführen der obigen Funktion an einem Array A mit Achsenlängen [6, 14, 9, 13, 17] (d. H. Ein 5-dimensionales Array) für die Iterationsnummer 98000 zu der Koordinate (3, 7, 2, 5, 12). Wie kann ich dies tun, d. H. Eine spezifische Iterationsnummer zu seiner Position in einem n-dimensionalen Array zuordnen? Und noch einmal, mein Ziel ist nicht, eine andere Funktion wie oben zu schreiben.

+0

Ich bin nicht sicher, ob ich das richtig verstanden, was Sie mit Ihrem aktuellen Lösung unglücklich macht? Ist es Geschwindigkeit? Ist es Code-Länge (Sie würden so viele wie möglich verwenden möchten)? Ist es so, dass Sie ein gigantisches Tupel erstellen und speichern, nur um darüber zu iterieren, und einen Iterator vorziehen würden, der Werte 1 mal 1 ausspuckt und dann vergisst? – Julien

+0

@JulienBernu Es ist nicht so viel Geschwindigkeit, ich fühle mich wie ein One-Liner sollte für dieses Problem existieren, aber ich kann nicht daran denken. – bjd2385

Antwort

0

Ich bin mir nicht sicher über das Beispiel, das Sie geben (Ihr Code ergibt ein anderes Ergebnis als das, das Sie angeben). Aber die eingebaute in Einzeiler die gleiche Operation zu tun ist, np.unravel_index:

import numpy as np 
import operator 
def product(iterable): 
    return reduce(operator.mul, iterable) 

def clock_1(iteration_number, axis_lengths): 
    dimension=len(axis_lengths) 
    coordinate = [] 
    for i in range(dimension): 
     s = axis_lengths[dimension-i-1:dimension-i][0] 
     g = iteration_number % s 
     iteration_number //= s 
     coordinate += [g] 
    return tuple(reversed(coordinate)) 

def clock_2(iteration_number, axis_lengths): 
    return np.unravel_index(iteration_number % product(axis_lengths), axis_lengths) 

print "clock_1:", clock_1(98000, (6,14,9,3,17)) 
print "clock_2:", clock_2(98000, (6,14,9,3,17)) 


clock_1: (3, 3, 4, 1, 12) 
clock_2: (3, 3, 4, 1, 12)