Die Frage ist ziemlich einfach (im Gegensatz zum Titel). Ich habe ein Tupel vom Typ:

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

Ich muss dies in ein kleineres Tupel umwandeln wie:

(a, b) = p

So dass a <- 1 und b <- (2, 3, 4, 5, 6)

BEARBEITEN:

Ich benötige Code für Python v2.7. Ich hätte auch erwähnen sollen, dass es Möglichkeiten gibt, dies zu tun, aber ich suche etwas Natürliches und etwas, bei dem ich mich nicht mit Indizes befassen muss. Beispielsweise.

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

Ist nicht erwünscht.

BEARBEITEN 2:

Im obigen Beispiel ist a eine ganze Zahl, während b unser neues Tupel ist. Die Idee hinter n-Tupel zu x-Tupel ist, dass die Länge des neuen Tupels kleiner ist als die des ursprünglichen. Im folgenden Beispiel haben wir 0-Tupel (Ints):

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

Wenn es jedoch Folgendes ist:

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

Dann haben wir a <- 1, b <- 2, c <-3, d <- None/Nothing.

1
p0lAris 26 Nov. 2013 im 10:12

5 Antworten

Beste Antwort

Für eine allgemeine Lösung:

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

Ergebnis:

>>> 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)]

Sie müssen also wissen, wie viele Elemente sich auf der linken Seite befinden, und dies der Funktion mitteilen (da dies im Gegensatz zu der erweiterten Syntax zum Entpacken von Tupeln in Python 3 nicht von selbst festgestellt werden kann).

3
Tim Pietzcker 26 Nov. 2013 im 06:33

Dadurch wird eine Liste rekursiv anhand einer Liste geteilter Indizes aufgeteilt.

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)

Verwendung

>>> 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], []]

Was Sie so verwenden können:

>>> a,b,c,d = split([1,2,3,4,5,6],[2,4,8])
0
bcorso 26 Nov. 2013 im 06:49

In Python2 muss die RHS auf die richtige Anzahl von Elementen entpackt werden, um der LHS zu entsprechen. Mit solchen Hacks können Sie Indizes vermeiden. Sie müssen jedoch noch wissen, wie viele Artikel dort ausgepackt werden müssen.

>>> p = (1, 2, 3, 4, 5, 6)
>>> a, b = (lambda a, *b:(a, b))(*p)
>>> a
1
>>> b
(2, 3, 4, 5, 6)
1
John La Rooy 26 Nov. 2013 im 06:37

Du kannst das

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

Dies ist ein Beispiel

>>> p = (1,2,3,4,5)
>>> a, b = p[0], p[1:]
>>> a
1
>>> b
(2, 3, 4, 5)
2
Deck 26 Nov. 2013 im 06:14

Wenn Sie Python 3 verwenden, ist dies mit dem erweiterten iterativen Entpacken erweitertem Triving trivial Syntax:

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

b wird in eine Liste aufgenommen, da die RHS beliebig iterierbar sein kann. Sie können jedoch b = tuple(b) ausführen, wenn Sie wirklich genau ein Tupel benötigen.

Dies weicht geringfügig von Ihren späteren Beispielen ab:

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

Diese Syntax ist in Python 2 bereits legal und wird das Richtige tun, wenn LHS und RHS dieselbe Anzahl von Elementen haben. Dies ist der einzige Fall, der in Python 2 funktioniert, ohne mit der Indizierung zu spielen.

Die Verwendung eines * funktioniert auch hier in Python 3, aber die Variable, an die Sie es anhängen, ist immer eine Liste - auch wenn es nur ein Element enthält:

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

Aber in Ihrem letzten Beispiel wird es ungefähr das tun, was Sie wollen:

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

Das heißt, d ist eher eine leere Liste als None.

2
lvc 26 Nov. 2013 im 06:34