List Structures

The concept of a list is similar to oureveryday notion of a list. We read off (access) items on our to-do list, add items, cross off (delete) items, and so forth. We look at the use of lists next.

  • A list is a linear data structure , meaning that its elements have a linear ordering. (First, second, ...)
  • Each item in the list is identified by its index value (location) .
  • Index starts with 0

There are common operations performed on lists including; retrieve, update, insert, delete, and append.

Lists in Python

  • Mutable
  • Flexible length
  • Allowing mixed type elements
  • index 0...n-1
  • denoted with [value1, value2]

In [11]:
["Watermelon"]


Out[11]:
['Watermelon']

In [14]:
list(123)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-abd6fc0281e6> in <module>()
----> 1 list(123)

TypeError: 'int' object is not iterable

In [13]:
list("123")


Out[13]:
['1', '2', '3']

In [8]:
a = []
b = list()

In [9]:
a == b


Out[9]:
True

In [5]:
x = [0,1,2,3,4,5,6]

In [ ]:
z = list()

In [6]:
y = list(range(7))

In [7]:
x == y


Out[7]:
True

In [18]:
type(['one', 'two'])


Out[18]:
list

In [19]:
type(['apples' , 50, False])


Out[19]:
list

In [20]:
type([]) # Empty list


Out[20]:
list

In [7]:
# Define a list
# Using list function to create empty list
a = list()
print(type(a))
print(a)


<type 'list'>
[]

In [8]:
# Using brackets to create empty list
b = []
print(type(b))
print(b)


<type 'list'>
[]

In [22]:
# We can also initilize lists with some content inside
c = [1,2,3] # Create list with integer values inside

In [12]:
# We can access specific elements of the list using index value
print(c[1])


2

In [13]:
print(c[0])


1

In [30]:
n = 0
tot1 = 0
while n < len(c):
    tot1 = tot1 + c[n]
    n  = n +1
tot1


Out[30]:
6

In [28]:
tot = sum(c)
tot


Out[28]:
6

In [27]:
total = c[0] + c[1] + c[2]
total


Out[27]:
6

In [28]:
# Creates a list of elements from 0 to 9
lst = list(range(10)) 
print(lst)


[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [ ]:
a = 10

In [29]:
# Lets update(replace) an element of the list called lst
lst[2] = 19
print(lst)


[0, 1, 19, 3, 4, 5, 6, 7, 8, 9]

In [30]:
# Let's remove an element from the list
del lst[2]
print(lst)


[0, 1, 3, 4, 5, 6, 7, 8, 9]

In [31]:
# We can add elements to the list using 2 different methods:

lst.insert(8,3) # adds element 3 at index 8
print(lst)


[0, 1, 3, 4, 5, 6, 7, 8, 3, 9]

In [32]:
lst.append(4) # adds element 4 at the end of list
print(lst)


[0, 1, 3, 4, 5, 6, 7, 8, 3, 9, 4]

Tuples in Python

In contrast to lists, tuple is defined and cannot be altered. Otherwise, lists and tuples are essentially same. To denote tuples we use ( )


In [34]:
nums = (10,20,30)

In [35]:
type(nums)


Out[35]:
tuple

In [36]:
print(nums[2])


30

In [37]:
nums.insert(1,15) # Non alterable


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-37-7832f7eaad89> in <module>()
----> 1 nums.insert(1,15) # Non alterable

AttributeError: 'tuple' object has no attribute 'insert'

In [38]:
del nums[2]


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-bd0caa505264> in <module>()
----> 1 del nums[2]

TypeError: 'tuple' object doesn't support item deletion

In [39]:
nums.append(40)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-39-724de97a802a> in <module>()
----> 1 nums.append(40)

AttributeError: 'tuple' object has no attribute 'append'

In [40]:
y = 75
x = 45

In [47]:
(x,y) = (y,x)

In [48]:
x


Out[48]:
75

In [49]:
y


Out[49]:
45

Sequences

A sequence in Python is a linearly ordered set of elements accessed by an index number.

Lists, tuples, and strings are all sequences.

We know what is string: "String"

Strings are also immutable like tuples, but we can we will use the intensively.

Let's look at more operations we can use with sequences:


In [50]:
# Initializing our variable 
s1 = 'hello'
s2 = 'world!'
t1 = (1,2,3,4)
t2 = (5,6)
l1 = ['apple', 'pear', 'peach']
l2 = [10,20,30,40,50,60,70]

Finding length with len():


In [51]:
# Finding length for string
print(len(s1))
print(len(s2))


5
6

In [52]:
# Finding length for tuples
print(len(t1))
print(len(t2))


4
2

In [51]:
# Finding length for lists
print(len(l1))
print(len(l2))


3
7

Accessing elements by indexing:


In [54]:
print(s1[0])
print(s2[4])


h
d

In [56]:
print(t1[1])


2

In [57]:
print(l2[2])


30

Slicing:


In [58]:
s1[1:4]


Out[58]:
'ell'

In [59]:
s2[3:]


Out[59]:
'ld!'

In [60]:
l1[1:]


Out[60]:
['pear', 'peach']

In [66]:
t1


Out[66]:
(1, 2, 3, 4)

In [67]:
t1[::-1] # Special Slicing feature


Out[67]:
(4, 3, 2, 1)

Counting elements:


In [68]:
s1.count('l') # Counting l occurences in the sequence


Out[68]:
2

In [69]:
l2


Out[69]:
[10, 20, 30, 40, 50, 60, 70]

In [70]:
l2.count(30)


Out[70]:
1

In [70]:
t1


Out[70]:
(1, 2, 3, 4)

In [72]:
t1.count(15)


Out[72]:
0

Finding Indexes from elements:


In [80]:
# c = s1.count("l") # 2
word = "This is a very nice day in Houston!"
user_input = input("Please enter a letter that I can find index for you: ")
i = 0
lst = []
c = word.count(user_input)
while i < len(word):
    if c > 1:
        if word[i] == user_input:
            lst.append(i)
    elif c == 0:
        print(0)
        break
    else:
        if word[i] == user_input:
            print(i)
            break
    i = i + 1
print(lst)


Please enter a letter that I can find index for you: i
[2, 5, 16, 24]

In [79]:
s1.index('l')


Out[79]:
2

In [81]:
l1.index('peach')


Out[81]:
2

In [82]:
t1.index(3)


Out[82]:
2

Checking Membership with in :


In [84]:
'h' in s1


Out[84]:
True

In [87]:
9 in t2


Out[87]:
False

In [89]:
30 in l2


Out[89]:
True

Concatenation:


In [91]:
s1, s2


Out[91]:
('hello', 'world!')

In [92]:
print(s1+s2)
print(s1 + " " +s2)


helloworld!
hello world!

In [93]:
print(t1+t2)


(1, 2, 3, 4, 5, 6)

In [96]:
print(l1+l2)


['apple', 'pear', 'peach', 10, 20, 30, 40, 50, 60, 70]

In [98]:
(s1 + " ")* 4


Out[98]:
'hello hello hello hello '

Finding minimum:


In [99]:
min(s2)


Out[99]:
'!'

In [100]:
min(t2)


Out[100]:
5

In [101]:
min(l1)


Out[101]:
'apple'

Finding maximum:


In [102]:
max(s2)


Out[102]:
'w'

In [103]:
max(t1)


Out[103]:
4

In [104]:
max(l1)


Out[104]:
'pear'

Lists and Tuples can used with more dimensions. Nested lists and tuples are giving this flexibility.


In [105]:
class_grades = [ [85, 91, 89], 
                 [78, 81, 86], 
                 [62, 75, 77] ]

In [106]:
class_grades


Out[106]:
[[85, 91, 89], [78, 81, 86], [62, 75, 77]]

When we trying to get the specific elements in nested lists or tuples, we should do something different:


In [107]:
class_grades[0] # Prints the first sub-list


Out[107]:
[85, 91, 89]

In [108]:
# We can get the specific item like this in a long way 
student1_grades = class_grades[0]
student1_exam1 = student1_grades[0]
student1_exam1


Out[108]:
85

In [109]:
# In short this is more conventional
class_grades[0][0]


Out[109]:
85

In [110]:
# Let's write a small script that calculates the class average.
k = 0
exam_avg = []
while k < len(class_grades):
    avg = (class_grades[k][0] + class_grades[k][1] + class_grades[k][2]) / 3.0
    exam_avg.append(avg)
    k += 1

format((sum(exam_avg) / 3.0), '.2f')


Out[110]:
'80.44'

Apply It!

Write a small program that finds your Chineze Zodiac and its characteristics using tuples and datetime module, resulting output:

This program will display your Chinese Zodiac Sign and Associated personal characteristics.

Enter your year of birth (yyyy): 1984
Your Chinese Zodiac sign is the Rat

Your personal charactersitics...
Forthright, industrious, sensitive, intellectual, sociable

Would you like to enter another year? (y/n): n


Here are the characteristics:
rat = 'Forthright, industrious, sensitive, intellectual, sociable'
ox = 'Dependable, methodical, modest, born leader, patient'
tiger = 'Unpredictable, rebellious, passionate, daring, impulsive'
rabbit = 'Good friend, kind, soft-spoken, cautious, artistic'
dragon = 'Strong, self-assured, proud. decisive, loyal'
snake = 'Deep thinker, creative, responsible, calm, purposeful'
horse = 'Cheerful, quick-witted, perceptive, talkative, open-minded'
goat = 'Sincere, sympathetic, shy, generous, mothering'
monkey = 'Motivator, inquisitive, flexible, innovative, problem solver'
rooster = 'Organizer, self-assured, decisive, perfectionist, zealous'
dog = 'Honest, unpretentious, idealistic, moralistic, easy going'
pig = 'Peace-loving, hard-working, trusting, understanding, thoughtful'

Test Time

Question1: Which of the following sequence types is a mutable type?

a) Strings
b) Lists
c) Tuples

Question2: What is the result of the following snippet:

lst = [4,2,9,1]
lst.insert(2,3)

a) [4,2,3,9,1]
b) [4,3,2,9,1]
c) [4,2,9,2,1]

Question3: Which of the following set of operations can be applied to any sequence?

a) len(s), s[i], s+w (concatenation)
b) max(s), s[i], sum(s) 
c) len(s), s[i], s.sort()

Iterating Over Sequences

We can iterate over sequences using while loop, the one that we learned last lecture. However there is a better and more Pythonic way, it is called For loops

  • For loops are used to construct definite loops.

Syntax:

for k in sequence:
    statements

In [4]:
nums = [10,20,30,40,50,60]
for k in nums:
    print(k)


10
20
30
40
50
60

In the example above k is called loop variable. In the list we had 6 elements so our loop iterated six times. We can create the same script with while loop as follows:


In [112]:
k = 0
while k < len(nums):
    print(nums[k])
    k += 1


10
20
30
40
50
60

For statement can be applied to all sequence types, including strings. Let's see how:


In [5]:
for ch in 'Hello World!':
    print(ch)


H
e
l
l
o
 
W
o
r
l
d
!

Now since we know about the beautiful for loops, it's time to learn a built-in function most commonly used with for loops: a built-in range() function


In [15]:
list(range(2))


Out[15]:
[0, 1]

In [17]:
list(range(2,11))


Out[17]:
[2, 3, 4, 5, 6, 7, 8, 9, 10]

In [23]:
list(range(1, 11, 2))


Out[23]:
[1, 3, 5, 7, 9]

As you can see range() function creates a list so we can use it with for loops:


In [27]:
tot = 0
for k in range(1, 11, 2):
    tot = tot + k
    print(k)
    
print("Total is", tot)


1
3
5
7
9
Total is 25

Test Time

Question1: For nums=[10,30,20,40] , what does the following for loop output?

for k in nums:
    print(k)

Questions2: For fruit='strawberry' , what does the following for loop output?

for k in range(0,len(fruit),2):
    print(fruit[k], end='')

Question3: For nums=[12, 4, 11, 23, 18, 41, 27] , what is the value of k when the while loop terminates?

k = 0
while k < len(nums) and nums[k] != 18:
    k += 1

In [29]:
nums=[12, 4, 11, 23, 18, 41, 27]
k = 0
while k < len(nums) and nums[k] != 18:
    k += 1
print(k)


4

In [28]:
fruit = "Strawberry"
for k in range(0, len(fruit),2):
    print(fruit[k], end='')


Srwer

List Comprehension

The range function allows for the generation of sequences of integers in fixed increments.

List Comprehensions in Python can be used to generate more varied sequences.


In [32]:
[x**2 for x in [1,2,3]]


Out[32]:
[1, 4, 9]

In [121]:
[x**2 for x in range(10)]


Out[121]:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

In [122]:
nums = [-1,1,-2,2,-3,3,-4,4,-5,5]
[x for x in nums if x >= 0]


Out[122]:
[1, 2, 3, 4, 5]

In [124]:
[ord(ch) for ch in 'Hello World']


Out[124]:
[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

In [125]:
vowels = ('a', 'e', 'i','o', 'u')
w = 'Hello World!'
[ch for ch in w if ch in vowels]


Out[125]:
['e', 'o', 'o']