3.2. Operations On Sequences

Next, we will look at how to interpret expressions involving sequences and various operators.

3.2.1. Concatenation and Repetition

In general, you cannot perform mathematical operations on lists. Interestingly, the + and * operator does work with lists, but for lists, the + operator concatenates lists and the * operator repeats the items in a list a given number of times. Concatenation means joining the two operands by linking them end-to-end. For example:

In [1]: fruit = ["apple", "orange", "banana", "cherry"]

In [2]: [1, 2] + [3, 4]
Out[2]: [1, 2, 3, 4]

In [3]: fruit + [6, 7, 8, 9]
Out[3]: ['apple', 'orange', 'banana', 'cherry', 6, 7, 8, 9]

In [4]: [0] * 4
Out[4]: [0, 0, 0, 0]

In [5]: [1, 2, ["hello", "goodbye"]] * 2
Out[5]: [1, 2, ['hello', 'goodbye'], 1, 2, ['hello', 'goodbye']]

It is important to see that these operators create new lists from the elements of the operand lists. If you concatenate a list with 2 items and a list with 4 items, you will get a new list with 6 items (not a list with two sublists). Similarly, repetition of a list of 2 items 4 times will give a list with 8 items.

One way for us to make this more clear is to run a part of this example in codelens. As you step through the code, you will see the variables being created and the lists that they refer to. Pay particular attention to the fact that when newlist is created by the statement newlist = fruit + numlist, it refers to a completely new list formed by making copies of the items from fruit and numlist. You can see this very clearly in the codelens object diagram. The objects are different.

(chp09_concatid)

In Python, every object has a unique identification tag. Likewise, there is a built-in function that can be called on any object to return its unique id. The function is appropriately called id and takes a single parameter, the object that you are interested in knowing about. You can see in the example below that a real id is usually a very large integer value (corresponding to an address in memory).

In [6]: alist = [4, 5, 6]

In [7]: id(alist)
Out[7]: 4566516040

Check your understanding

    rec-5-29: What is printed by the following statements?

    alist = [1, 3, 5]
    blist = [2, 4, 6]
    print(alist + blist)
    
  • (A) 6
  • Concatenation does not add the lengths of the lists.
  • (B) [1, 2, 3, 4, 5, 6]
  • Concatenation does not reorder the items.
  • (C) [1, 3, 5, 2, 4, 6]
  • Yes, a new list with all the items of the first list followed by all those from the second.
  • (D) [3, 7, 11]
  • Concatenation does not add the individual items.

    rec-5-30: What is printed by the following statements?

    alist = [1, 3, 5]
    print(alist * 3)
    
  • (A) 9
  • Repetition does not multiply the lengths of the lists. It repeats the items.
  • (B) [1, 1, 1, 3, 3, 3, 5, 5, 5]
  • Repetition does not repeat each item individually.
  • (C) [1, 3, 5, 1, 3, 5, 1, 3, 5]
  • Yes, the items of the list are repeated 3 times, one after another.
  • (D) [3, 9, 15]
  • Repetition does not multiply the individual items.

3.2.2. Operations on Strings

In general, you cannot perform mathematical operations on strings, even if the strings look like numbers. The following are illegal (assuming that message has type string):

In [8]: message = "Hi!"

In [9]: message - 1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-61ad35376c4a> in <module>()
----> 1 message - 1

TypeError: unsupported operand type(s) for -: 'str' and 'int'

In [10]: "Hello" / 123
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-f9d3d3f84fca> in <module>()
----> 1 "Hello" / 123

TypeError: unsupported operand type(s) for /: 'str' and 'int'

In [11]: message * "Hello"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-e2613568ab04> in <module>()
----> 1 message * "Hello"

TypeError: can't multiply sequence by non-int of type 'str'

In [12]: "15" + 2
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-01703460fe91> in <module>()
----> 1 "15" + 2

TypeError: Can't convert 'int' object to str implicitly

Like with lists, the + operator concatenates strings and the * operator repeats the items in a string a given number of times. For example:

The output of this program is banana nut bread. The space before the word nut is part of the string and is necessary to produce the space between the concatenated strings. Take out the space and run it again.

As with lists, the * operator also works on strings, performing repetition. For example, 'Fun'*3 is 'FunFunFun'. One of the operands has to be a string and the other has to be an integer.

In [13]: "Go" * 6
Out[13]: 'GoGoGoGoGoGo'

In [14]: name = "Packers"

In [15]: name * 3
Out[15]: 'PackersPackersPackers'

In [16]: name + "Go" * 3
Out[16]: 'PackersGoGoGo'

In [17]: (name + "Go") * 3
Out[17]: 'PackersGoPackersGoPackersGo'

This interpretation of + and * makes sense by analogy with addition and multiplication. Just as 4*3 is equivalent to 4+4+4, we expect "Go"*3 to be the same as "Go"+"Go"+"Go", and it is. Note also in the last example that the order of operations for * and + is the same as it was for arithmetic. The repetition is done before the concatenation. If you want to cause the concatenation to be done first, you will need to use parenthesis.

Check your understanding

    rec-5-31: What is printed by the following statements?

    s = "python"
    t = "rocks"
    print(s + t)
    
  • (A) python rocks
  • Concatenation does not automatically add a space.
  • (B) python
  • The expression s+t is evaluated first, then the resulting string is printed.
  • (C) pythonrocks
  • Yes, the two strings are glued end to end.
  • (D) Error, you cannot add two strings together.
  • The + operator has different meanings depending on the operands, in this case, two strings.

    rec-5-32: What is printed by the following statements?

    s = "python"
    excl = "!"
    print(s+excl*3)
    
  • (A) python!!!
  • Yes, repetition has precedence over concatenation
  • (B) python!python!python!
  • Repetition is done first.
  • (C) pythonpythonpython!
  • The repetition operator is working on the excl variable.
  • (D) Error, you cannot perform concatenation and repetition at the same time.
  • The + and * operator are defined for strings as well as numbers.

3.2.3. Length

The len function, when applied to a string, returns the number of characters in a string.

In [18]: fruit = "Banana"

In [19]: len(fruit)
Out[19]: 6

As with strings, the function len returns the length of a list (the number of items in the list). However, since lists can have items which are themselves lists, it important to note that len only returns the top-most length. In other words, sublists are considered to be a single item when counting the length of the list.

In [20]: alist =  ["hello", 2.0, 5, [10, 20]]

In [21]: len(alist)
Out[21]: 4

In [22]: len(['spam!', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]])
Out[22]: 4

Check your understanding

    rec-5-33: What is printed by the following statements?

    s = "python rocks"
    print(len(s))
    
  • (A) 11
  • The blank counts as a character.
  • (B) 12
  • Yes, there are 12 characters in the string.

    rec-5-34: What is printed by the following statements?

    alist = [3, 67, "cat", 3.14, False]
    print(len(alist))
    
  • (A) 4
  • len returns the actual number of items in the list, not the maximum index value.
  • (B) 5
  • Yes, there are 5 items in this list.

    rec-5-35: What is printed by the following statements?

    alist = [3, 67, "cat", [56, 57, "dog"], [ ], 3.14, False]
    print(len(alist))
    
  • (A) 7
  • Yes, there are 7 items in this list even though two of them happen to also be lists.
  • (B) 8
  • len returns the number of top level items in the list. It does not count items in sublists.
Next Section - 3.3. Accessing Sequence Data