2013-08-07 17 views
5
if n == 1: return [(-1,), (1,)] 
if n == 2: return [(-1,0), (1,0), (0,-1), (0,1)] 
if n == 3: return [(-1,0,0), (1,0,0), (0,-1,0), (0,1,0), (0,0,-1), (0,0,1)] 

In pratica, restituire un elenco di tuple 2n conformi alle specifiche precedenti. Il codice sopra funziona bene per i miei scopi, ma mi piacerebbe vedere una funzione che funziona per tutti n ∈ ℕ (solo per l'edificazione). Compreso tuple([0]*n) nella risposta è accettabile da me.Qual è il modo pitone di generare questo tipo di lista? (Facce di un n-cubo)

Lo sto utilizzando per generare la direzione delle facce di un politopo di misura. Per tutte le direzioni, posso usare list(itertools.product(*[(0, -1, 1)]*n)), ma non riesco a trovare qualcosa di abbastanza conciso solo per le direzioni del viso.

+2

probabilmente sarei a smettere di pensarci e utilizzare un 'ciclo for'. – user2357112

+2

Ehm .. * "Code Golf non è più in tema per Overflow dello stack" *. – arshajii

+0

@arshajii: non è strettamente golf. Come puoi vedere, la risposta più votata non è il golf. – rhombidodecahedron

risposta

5
def faces(n): 
    def iter_faces(): 
     f = [0] * n 
     for i in range(n): 
      for x in (-1, 1): 
       f[i] = x 
       yield tuple(f) 
      f[i] = 0 
    return list(iter_faces()) 

>>> faces(1) 
[(-1,), (1,)] 
>>> faces(2) 
[(-1, 0), (1, 0), (0, -1), (0, 1)] 
>>> faces(3) 
[(-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)] 
2
>>> set(itertools.permutations([1] + [0]*(n-1))) | set(itertools.permutations([-1] + [0]*(n-1))) 
+2

Il runtime superexponential rende questa una cattiva idea. Inoltre, le tuple risultanti hanno un '0' troppe. – user2357112

+1

Risolto il problema 'n'. La risposta è ovviamente inadatta per un grande 'n', ma lascerò perdere. – roippi

3
[tuple(sign * (i == p) for i in range(n)) for p in range(n) for sign in (-1, 1)] 

Pianura for, non implicita boolint equivalente:

for p in range(n): 
    for sign in (-1, 1): 
     yield tuple((sign if i == p else 0) for i in range(n)) 
+3

One-liner, ma ci vuole un po 'per capire, e le clausole 3 'for' sono un po' troppo. – user2357112

3

Il modo in cui sto vedendo questo problema è di due i simultanea nterleaving n spostamento dimensioni registra

>>> def shift_register(n): 
    l1 = (-1,) + (0,)*(n - 1) 
    l2 = (1,) + (0,)*(n - 1) 
    while any(l1): 
     yield l1 
     yield l2 
     l1 = (0,) + l1[:-1] 
     l2 = (0,) + l2[:-1] 


>>> list(shift_register(3)) 
[(-1, 0, 0), (1, 0, 0), (0, -1, 0), (0, 1, 0), (0, 0, -1), (0, 0, 1)] 
3

Una soluzione con numpy:

>>> a = numpy.identity(3, dtype=int) 
>>> numpy.hstack((a, -a)).reshape(6, 3) 
array([[ 1, 0, 0], 
     [-1, 0, 0], 
     [ 0, 1, 0], 
     [ 0, -1, 0], 
     [ 0, 0, 1], 
     [ 0, 0, -1]]) 
Problemi correlati