.. _ch03-python-tuples: =============================================================== Tuples =============================================================== A tuple is a sequence of values. The values can be any type, and they are indexed by integers, so in that respect, tuples are a lot like lists. The important difference though, is that tuples are **immutable**. A tuple is a **comma-separated** list of values, with or without in parentheses:: >>> t = 'a', 'b', 'c', 'd', 'e' which is the same as:: >>> t = ('a', 'b', 'c', 'd', 'e') How can we create a tuple with a single element? One may try:: >>> t = ('a') >>> type(t) which is not what we wanted. A correct way is to put a final comma:: >>> t = ('a',) # or equivalently, t = 'a', >>> type(t) To create an empty tuple, we can use the built-in function ``tuple()``:: >>> t = tuple() >>> type(t) >>> print t () If we include an argument in a form of a sequence (string, list or tuple) when using ``tuple``, we get a tuple with the elements of the sequence. For a string input:: >>> t='apple' >>> print tuple(t) ('a', 'p', 'p', 'l', 'e') For a list input:: >>> t=[1,2,3] >>> print tuple(t) (1, 2, 3) For a tuple input:: >>> t='a','b','c' >>> t1= tuple(t) ('a', 'b', 'c') >>> print t1[0] 'a' >>> t is t1 True >>> id(t) == id(t1) True For a dictionary input, we only get key elements with no particular order:: >>> t={'one':'hana','two':'dool'} >>> t1 = tuple(t) >>> print t1 ('two', 'one') >>> t1[1] 'one' .. note:: In general, you can convert type A to type B by using any built-in function such as ``list``, ``tuple``, ``dict``, ``str``, ``float``, ``int``, etc.:: >>> B=list(A) >>> B=tuple(A) >>> B=str(A) and so on. Tuple assignments -------------------------------------------------- We have seen this already, but let's refresh our memory again. A tuple assignement is an elegant way to assign multiple values in a single line:: >>> a,b = 1,2 and we can also swap them:: >>> print a,b 1 2 >>> a, b = b, a >>> print a,b 2 1 Tuples as return values ------------------------------------------------------- When we specify return values, we can also return multiple values:: >>> def min_max(t): ... return min(t),max(t) >>> t = [1,2,3] >>> min_max(t) (1,3) >>> t={'one':'hana','two':'dool','three':'set'} >>> t1=tuple(t) >>> t1 ('three', 'two', 'one') >>> min_max(t1) ('one', 'two') >>> min_max(t.values()) ('dool', 'set') Variable-length argument tuples ------------------------------------------------------- Functions can take a variable number of arguments. A parameter name that begins with ``*`` *gathers* arguments into a tuple. For instance, ``printall`` takes any number of arguments and prints all of them:: >>> def printall(*args): ... print args >>> printall(1,'a',159,{'one':'hana'}) (1, 'a', 159, {'one': 'hana'}) This special syntax, ``*args``, is for any variable numbers of inputs that are ``non-keyworded``, while ``**kwargs`` is for ``key-worded`` inputs. An example with ``**kwargs`` as a function argument produces a dictionary as output:: >>> def printall(**kwargs): ... print kwargs >>> printall(key1=1,key2='a',key3=159,key4={'one':'hana'}) {'key3': 159, 'key2': 'a', 'key1': 1, 'key4': {'one': 'hana'}} You will get an error if you specify an argument without a keyword, i.e., ``key=...``:: >>> printall('ams209') Traceback (most recent call last): File "", line 1, in TypeError: printall() takes exactly 0 arguments (1 given) See more examples `here `_. Lists and tuples, dictionaries and tuples ------------------------------------------------------- We can use the built-in function ``zip`` which takes two or more sequences to create a list of tuples where each tuple contains one element from each sequence. For example:: >>> s='abc' >>> t=[0,1,2] >>> z=zip(s,t) >>> print z [('a', 0), ('b', 1), ('c', 2)] The result is a list of tuples where each tuple contains a character from the string ``s`` and the corresponding element from the list ``t``. Furthermore, we can convert the resulting list into a dictionary using ``dict``:: >>> dict(z) {'a': 1, 'c': 3, 'b': 2} This is a concise way to create a dictionary combining ``zip`` and ``dict``. Another example we can immediately think of is:: >>> e=['one','two','three'] >>> k=['hana','dool','set'] >>> eng2kor=zip(e,k) >>> eng2kor [('one', 'hana'), ('two', 'dool'), ('three', 'set')] >>> eng2kor=dict(eng2kor) {'three': 'set', 'two': 'dool', 'one': 'hana'} One can also go in the other direction using ``items``, i.e., you can use a dictionary to create a list of tuples. Continuing from the last execution:: >>> type(eng2kor) >>> eng2kor.items() [('three', 'set'), ('two', 'dool'), ('one', 'hana')] >>> type(eng2kor.items()) In case the sequences are not the same length, the result has the length of the shorter one:: >>> zip('ams','0123456789','$#@!%') [('a', '0', '$'), ('m', '1', '#'), ('s', '2', '@')]