# Tupel - unveränderliche Sequenzen
#
# Zweck:
# - effizienter als Listen
# - nutzbar als Keys von Dictionaries
# - manche Funktionen fordern Tupel, z.B. die String-Methoden startswith/endswith
# - auch beim Formatierungs-Operator % werden Tupel gefordert

# leeres Tupel
tupel0 = ()
print(tupel0)

# einelementiges Tupel (Singleton) mit Komma am Ende
tupel1 = 1,
print(tupel1)

# mehrelementiges Tupel
tupel = 1, 2, 3

for i in 1, 2, 3: print(i)
print()

# explizite Tupel-Klammerung bei nicht leeren Tupeln generell möglich, aber bei
# Tupel-Zuweisungen und Schleifen nicht nötig
tupel1 = (1,)
tupel = (1, 2, 3)
for i in (1, 2, 3): print(i)
print()

# Indexierung
print(tupel[1], tupel[-1])

# Slicing
print(tupel[0:2])

# Sequence Unpacking
a, b, c = tupel
print(a, b, c)

# Vertauschen zweier Variableninhalte
a = 3
b = 4
a, b = b, a # Tupel (b, a) wird nach a und b entpackt
print(a, b)

# Tupel kennen + und *
print(tupel + tupel, tupel * 2)
print(tupel + tuple('abcd') + tuple([4, 5, 6]))
print()

# Formatierung mit %: Tupel erforderlich
print('%d %d %d' % tupel)
if 0:
    print('%d %d %d' % list(tupel)) # TypeError: %d format: a number is required, not list
    print('%s %s %s' % list(tupel)) # TypeError: not enough arguments for format string

# mit format() statt %
print('{:d} {:d} {:d}'.format(*tupel))

# Python 3 unterstützt Extended Iterable Unpacking
a, *b, c = 2 * tupel
print(a, b, c)        # 1 [2, 3, 1, 2] 3
a, b, *c = tupel + (4, 5)
print(a, b, c)        # 1 2 [3, 4, 5]
