/ / Python: Converti n-tupla in x-tuple dove x <n - python, python-2.7, tuple

Python: Converti n-tupla in x-tuple dove x <n - python, python-2.7, tuple

La domanda è piuttosto semplice (a differenza del titolo). Ho una tupla del tipo:

p = (1, 2, 3, 4, 5, 6)
# I refer to this as a 6-tuple but p could be an n-tuple

Devo convertire questo in una tupla più piccola come:

(a, b) = p

così a <- 1 e b <- (2, 3, 4, 5, 6)

MODIFICARE:

Ho bisogno di codice per Python v2.7. Inoltre, avrei dovuto dire che ci sono modi per farlo, ma sto cercando qualcosa di naturale e qualcosa in cui non ho bisogno di trattare gli indici, ad esempio.

a, b, c, d, e = p[0], p[1], p[2], p[3], p[4], p[5:]

non è desiderato

MODIFICA 2:

Nell'esempio sopra, a è un numero intero mentre bè la nostra nuova tupla. L'idea che sta dietro n-tuple to x-tuple è che la lunghezza della nuova tupla è minore di quella originale. Nell'esempio seguente abbiamo 0-tuple (ints):

a, b, c = (1, 2, 3)

Tuttavia, se è il seguente:

a, b, c, d = (1, 2, 3)

Poi abbiamo a <- 1, b <- 2, c <-3, d <- None/Nothing.

risposte:

3 per risposta № 1

Per una soluzione generale:

def split_after(lst, n):
for i in range(n):
yield lst[i]
yield lst[n:]

Risultato:

>>> a,b,n = split_after(p,2)
>>> a
1
>>> b
2
>>> n
(3, 4, 5, 6)
>>> l = list(split_after(p,3))
>>> l
[1, 2, 3, (4, 5, 6)]

Quindi devi sapere quanti oggetti haiil lato sinistro e dirlo alla funzione (perché non può dirlo da solo, a differenza di ciò che la sintassi estesa di disimpaccatura tupla in Python 3 ti permette di fare).


2 per risposta № 2

Puoi farlo

a, b = p[0], p[1:]

Questo è un esempio

>>> p = (1,2,3,4,5)
>>> a, b = p[0], p[1:]
>>> a
1
>>> b
(2, 3, 4, 5)

2 per risposta № 3

Se stai usando Python 3, questo è banale usando il esteso disimballaggio iterabile sintassi:

>>> p = (1, 2, 3, 4, 5, 6)
>>> a, *b = p
>>> a
1
>>> b
[2, 3, 4, 5, 6]

b viene inserito in un elenco poiché l'RHS può essere qualsiasi iterabile, ma è possibile farlo b = tuple(b) se hai davvero bisogno che sia esattamente una tupla.

Questo varia leggermente dai tuoi esempi successivi:

a, b, c = (1, 2, 3)

Questa sintassi è già legale in Python 2 e farà la cosa giusta nel caso in cui LHS e RHS abbiano lo stesso numero di elementi. Questo è il solo caso che funzionerà in Python 2 senza giocare con l'indicizzazione.

Usare un * funzionerà anche qui in Python 3, ma la variabile che si allega a volontà sempre sii una lista - anche se ha solo un oggetto:

>>> a,b,*c = (1, 2, 3)
>>> c
[3]

Ma nel tuo ultimo esempio, farà approssimativamente quello che vuoi:

a, b, c, *d = (1, 2, 3)
>>> d
[]

vale a dire, d è una lista vuota piuttosto che None.


1 per risposta № 4

In Python2, l'RHS deve decomprimere il numero corretto di elementi in modo che corrispondano a LHS. Puoi evitare gli indici con hack come questo. Ma hai ancora bisogno della conoscenza del numero di oggetti da disfare.

>>> p = (1, 2, 3, 4, 5, 6)
>>> a, b = (lambda a, *b:(a, b))(*p)
>>> a
1
>>> b
(2, 3, 4, 5, 6)

0 per risposta № 5

Questo suddivide ricorsivamente un elenco basato su un elenco di indici divisi.

def split(lis, splits):
if not splits:
return [lis]
new_splits = [s - splits[0] for s in splits[1:]]
return [lis[:splits[0]]] + split(lis[splits[0]:], new_splits)

uso

>>> split([1,2,3,4,5,6],[2])
[[1,2], [3,4,5,6]]

>>> split([1,2,3,4,5,6],[2,4])
[[1,2], [3,4], [5,6]]

>>> split([1,2,3,4,5,6],[2,4,8])
[[1,2], [3,4], [5,6], []]

Quale puoi usare in questo modo:

>>> a,b,c,d = split([1,2,3,4,5,6],[2,4,8])