.. _ch03-python-variables-operations: =============================================================== Python data manipulations with operations =============================================================== Type ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In Python an easy way to check what type of a value you have is to use one of the the Python's build-in functions ``type()``. Let us take a look at how we can use it for various types of values:: >>> type("hello ams 209!") >>> type(159) >>> type(1.59) >>> type('1.59') >>> a=[1,2,3] >>> type(a) >>> id(a) 4303245536 >>> a=(1,2,3) >>> type(a) >>> id(a) 4303122336 .. _ch03-python-keywords: Python keywords ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ There are 31 keywords in Python 2 that are prohibited from using them as variable names in codes:: and as assert break class continue def del elif else except exec finally for from global if import in is lambda not or pass print raise return try while with yield In Python 3, ``exec`` is no longer a keyword, but ``nonlocal`` is. If the interpreter complains about one of your variable names and you are not sure why, see if it is on this list. Operators and operands ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The operators include: * ``+`` (addition):: >>> 5 + 3.1 8.1 * ``-`` (subtraction):: >>> 5-3 2 >>> 5.0-3 2.0 >>> 5.-3. 2.0 >>> 0+213 213 >>> 0+0213 139 >>> 0218 File "", line 1 0218 ^ SyntaxError: invalid token # why??? See how to create integers in binary, octal, and hexadecimal forms: * `article 1 `_ * `article 2 `_ * ``*`` (multiplication):: >>> 4*3 12 >>> 4.*3 12.0 >>>1*2132 2132 >>> 1*02132 1114 # why??? * ``/`` (division):: >>> 3/5 0 >>> 3./5 0.6 >>> 3/5. 0.6 * ``**`` (exponentiation, not ``^``):: >>> 5**2 25 >>> 5**2. 25.0 * ``//`` (floor division -- chops off the fraction part):: >>> 5.//3. 1.0 >>> 5./3. 1.6666666666666667 * ``%`` (modulus operator):: >>> remainder = 7 % 3 >>> print remainder 1 >>> remainder = 7 % 3. >>> print remainder 1.0 In the above we note that when two operands are both integers the result is also integer; if at least one of them is real (``float``) the result is real. Data manipulations ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ We can also form a ``list`` whose elements are **not** the same type. For instance:: >>> a=[1,'b',1.59,"hello ams 209",(-1,3,5),[1,(2,'apple')]] >>> type(a) # which is a >>> type(a[1]) # which is 'b' >>> type(a[-1]) # which is [1,(2,'apple')] >>> type(a[-1][0]) # which is 1 >>> type(a[-1][1]) # which is (2,'apple') >>> type(a[-1][1][1]) # which is 'apple' >>> type(a[-1][1][0]) # which is 2 Since a ``list`` is mutable, we can easily modify it:: >>> a.append(True) >>> type(a[-1]) >>> b = ['we love scientific computing', 'my grade will be', 'A',209] >>> a.extend(b) >>> a [1, 'b', 1.59, 'hello ams 209', (-1, 3, 5), [1, (2, 'apple')], True, 'we love scientific computing', 'my grade will be', 'A', 209] >>> a[3],a[7],a[8:9] ('hello ams 209', 'we love scientific computing', ['my grade will be']) >>> a[3],a[7],a[8:10] ('hello ams 209', 'we love scientific computing', ['my grade will be', 'A']) >>> a[3],a[7],a[8]+' '+a[9] ('hello ams 209', 'we love scientific computing', 'my grade will be A') .. note:: What is the difference between ``a.append(b)`` and ``a.extend(b)``? Now let's change your grade from `A` to `A+`:: >>> for i, value in enumerate(a): ... if value is 'A': ... print i,value ... a[i] = 'A+' ... 9 A >>> a [1, 'b', 1.59, 'hello ams 209', (-1, 3, 5), [1, (2, 'apple')], True,'we love scientific computing', 'my grade will be', 'A+', 209] which will upgrade your grade from `A` to `A+`, even with a better output style as a regular sentence instead of a ``list`` this time:: >>> a[3]+', '+a[7] +', ' + a[8]+' '+a[9] +'!' 'hello ams 209, we love scientific computing, my grade will be A+!' Now you are wondering if you can change ``we`` to ``I`` in order to express your strong love and passion of AMS209 much better. So, you first check:: >>> a[7][0:2] 'we' Bravo! It may look like you can simply replace ``a[7][0:2]`` with ``I`` then! Now you try:: >> a[7][0:2] = 'I' Traceback (most recent call last): File "", line 1, in TypeError: 'str' object does not support item assignments This happens because the Python's ``string`` is **not** mutable, it is immutable. Sigh... But let's not worry. We can still do the following:: >>> b='I' + a[7][2:] >>> b 'I love scientific computing' We can now complete the task as we wanted:: >>> a[7] = b >>> a [1, 'b', 1.59, 'hello ams 209', (-1, 3, 5), [1, (2, 'apple')], True,'I love scientific computing', 'my grade will be', 'A+', 209] >>> a[3]+', '+a[7] +', ' + a[8]+' '+a[9] +'!' 'hello ams 209, I love scientific computing, my grade will be A+!' Let's play around the list ``a`` bit more. This time, let's think about how we can capitalize some characters of the elements in ``a``, say, we wish to change the first alphabet ``h`` to ``H`` and ``ams`` to ``AMS``. In this case we can use Python's built-in function ``upper`` which invokes on the given ``string``, in this case, ``a[3]``. For instance:: >>> b=a[3].upper() >>> b 'HELLO AMS 209' Wait a minute! This just changed all of the characters in the string into capital letters. Can we fix it? We can use the similar approach as we replaced ``we`` with ``I`` in the above:: >>> c=b[0]+a[3][1:5]+b[5:] >>> c 'Hello AMS 209' >>> a[3]=c >>> a [1, 'b', 1.59, 'Hello AMS 209', (-1, 3, 5), [1, (2, 'apple')], True,'I love scientific computing', 'my grade will be', 'A+', 209] >>> a[3]+', '+a[7] +', ' + a[8]+' '+a[9] +'!' 'Hello AMS 209, I love scientific computing, my grade will be A+!' Another way is to use two string methods ``split`` and ``list`` as below:: >>> k=b.split() >>> k ['HELLO', 'AMS', '209'] >>> list(k[0]) ['H', 'E', 'L', 'L', 'O'] The above two lines can be collapsed into one:: >>> k0=list(b.split()[0]) >>> k0 ['H', 'E', 'L', 'L', 'O'] Let's proceed more with two string methods of ``append`` and ``lower``:: >>> update=[] >>> for i,value in enumerate(k0): ... if i > 0: ... update.append(value.lower()) ... else: ... update.append(value) ... >>> update ['H', 'e', 'l', 'l', 'o'] We now need an inverse of ``split``, which can be done by using string method called ``join`` in order to concatenate the elements of ``update``. When doing so, it is useful to invoke the method on the delimiter and pass the list as a parameter:: >>> delimiter = '' # delimiter is a string with no space. >>> d=delimiter.join(update) >>> d 'Hello' You can also use a different spacing:: >>> delimiter2 = ' ' # delimiter1 is a string with one space. >>> delimiter.join(update[0:2]) + delimiter2.join(update[2:]) 'Hel l o' We now replace the first element of ``k`` with ``d``:: >>> k[0]=d >>> k ['Hello', 'AMS', '209'] Using a delimiter, this time with ``-`` between the elements, we have:: >>> delimiter = '-' >>> kNew=delimiter.join(k) >>> kNew 'Hello-AMS-209' Let us finish our task now slightly different way, using a list method ``del``:: >>> a [1, 'b', 1.59, 'Hello AMS 209', (-1, 3, 5), [1, (2, 'apple')], True, 'I love scientific computing', 'my grade will be', 'A+', 209] >>> a[3]=kNew >>> a [1, 'b', 1.59, 'Hello-AMS-209', (-1, 3, 5), [1, (2, 'apple')], True, 'I love scientific computing', 'my grade will be', 'A+', 209] >>> del a[0:3] >>> a ['Hello-AMS-209', (-1, 3, 5), [1, (2, 'apple')], True, 'I love scientific computing', 'my grade will be', 'A+', 209] >>> del a[1:4] >>> a ['Hello-AMS-209', 'I love scientific computing', 'my grade will be', 'A+', 209] >>> del a[-1] >>> a ['Hello-AMS-209', 'I love scientific computing', 'my grade will be', 'A+'] Using a space as a ``delimiter`` again, we get:: >>> delimiter=' ' >>> delimiter.join(a) 'Hello-AMS-209 I love scientific computing my grade will be A+' One can always split characters with word boundaries defined by ``delimiter``. If we wish to split ``Hello-AMS-200``, we can do:: >>> a[0] 'Hello-AMS-209' >>> delimiter='-' >>> f=a[0].split(delimiter) >>> f ['Hello', 'AMS', '209'] Again, if we invoke ``join`` on a string with one empty space ``''``:: >>> ' '.join(f) # Note here we directly used ' ' instead of using a variable delimiter to define it. 'Hello AMS 209'