Chapter 3 Built-In Data Structure
3.1 Tuple
Tuple is an immutable list. Any attempt to change/update tuple will return error. It can contain different types of object just like list.
Benefits of tuple against List are:
- Tuple is Faster than list
- Tuple Protects your data against accidental change
- Can be used as key in dictionaries, list can’t
3.1.1 Creation
Tuple is created through assignment with or without brackets. To create tuple from list, use tuple() constructor.
= (1,2,3,'o',(4,5,6)) ## with brackets
t1 = 1,2,3,'o','apple', (4,5,6) ## without brackets
t2 = tuple([1,2,3,'o','apple', (4,5,6)]) ## create from list using constructor
t3
print(type(t1), type(t2), type(t3))
## <class 'tuple'> <class 'tuple'> <class 'tuple'>
3.1.2 Accessor
Assessing single element returns the element. Assessing range of elements returns tuple.
print( t1[0], t1[1:3] )
## 1 (2, 3)
3.1.3 Copy and Clone
Use normal assignment = to duplicate. Reference of the memory address is copied. Data is actually not duplicated in memory. To clone an tuple (different ID), convert to list then back to tuple again.
## Copy actually points to the same memory location
= (1,2,3,4,5)
original = original
copy_test = tuple(list(original)) ## convert to list then back to tuple
clone_test
## The copy refers to the same content
print(original)
## (1, 2, 3, 4, 5)
print(copy_test)
## (1, 2, 3, 4, 5)
print(clone_test)
## Copy and original has the same memory location.
## (1, 2, 3, 4, 5)
print('Original ID: ', id(original))
## Original ID: 2145172309232
print('Copy ID: ', id(copy_test))
## Copy ID: 2145172309232
print('Clone ID: ', id(clone_test)) ## clone has different ID
## Clone ID: 2145172570256
3.2 List
- List is a collection of ordered items, where the items can be different data types
- You can pack list of items by placing them into []
- List is mutable
3.2.1 Creation
## Create Empty List
= [] # literal assignment method
empty = list() # constructor method
empty
= [123,'abc',456, None] ## multiple datatypes allowed
multiple = list('hello') ## [split into h,e,l,l,o]
str_list
multiple str_list
## [123, 'abc', 456, None]
## ['h', 'e', 'l', 'l', 'o']
3.2.2 Accessor
Use [] to specify single or range of objects to return. Index numner starts from 0.
= ['bread', 'noodle', 'rice', 'biscuit','jelly','cake']
food
## Accessing Single Index, Returns Object
2] # 3rd item
food[-1] # last item
food[
## Accessing Range Of Indexes, Return List
4] # first 3 items
food[:-3:] # last 3 items
food[1:5] # item 1 to 4
food[5:2:-1] # item 3 to 5, reverse order
food[-1] # reverse order food[::
## 'rice'
## 'cake'
## ['bread', 'noodle', 'rice', 'biscuit']
## ['biscuit', 'jelly', 'cake']
## ['noodle', 'rice', 'biscuit', 'jelly']
## ['cake', 'jelly', 'biscuit']
## ['cake', 'jelly', 'biscuit', 'rice', 'noodle', 'bread']
3.2.3 Methods
All methods shown below is “inplace”, meaning the original data will be changed.
Remove Item(s)
Removal of non-existence item will result in error
= list(['bread', 'noodle', 'rice', 'biscuit','jelly','biscuit','noodle'])
food 'biscuit') ## remove first found element
food.remove(## remove last element, and return it
food.pop() 1) ## remove second element, and return it
food.pop( food
## 'noodle'
## 'noodle'
## ['bread', 'rice', 'jelly', 'biscuit']
Appending
There are two methods to add elements to the tail. append() adds single element. extend() addes multiple elements.
'durian') ## add single element to the tail
food.append('nand','puff']) ## add elements to the tail
food.extend([ food
## ['bread', 'rice', 'jelly', 'biscuit', 'durian', 'nand', 'puff']
Other Methods
## ordering of elements
## reverse current order
food.reverse() ## sort ascending
food.sort() =True) ## sort descending
food.sort(reverse
food
## methods returning number
'biscuit') ## return the index of first found element
food.index('biscuit') ## return occurance of element food.count(
## ['rice', 'puff', 'nand', 'jelly', 'durian', 'bread', 'biscuit']
## 6
## 1
3.2.4 Operators
Concatenation
Two lists can be concatenated using ‘+’ operator.
= ['dog','cat','horse'] + ['elephant','tiger'] + ['sheep'] animals
List is Mutable
The reference of list variable won’t change after adding/removing its item
id(animals)
+= ['chicken']
animals
animals.pop()id(animals) ## ID had not changed
## 2145172581760
## 'chicken'
## 2145172581760
Copy and Clone
Assignment to another variable always refers to the same data.Use copy() method if you wish to clone the data, with different ID.
= [1,2,3,4,5] ## original data
original = original ## same ID as Original
copy_test = original.copy() ## different ID
clone_test print( id(original), id(copy_test), id(clone_test))
## 2145172612096 2145172612096 2145172617408
Passing To Function As Reference
When passing list to functions, only the reference passed. Meaning all changes to the list within the function will be reflected outside the function.
= [1,2,3,4,5]
my_list
def func(x):
print (x)
print('ID in Function: ', id(x))
6) ## modify the refrence
x.append(
my_listid(my_list)
## passing reference to function
func(my_list)
## content was altered
my_list id(my_list)
## [1, 2, 3, 4, 5]
## 2145172617472
## [1, 2, 3, 4, 5]
## ID in Function: 2145172617472
## [1, 2, 3, 4, 5, 6]
## 2145172617472
3.2.5 Iteration
For Loop
= ['abc','abcd','bcde','bcdee','cdefg']
mylist for x in mylist:
if 'abc' in x:
print (x)
## abc
## abcd
List Comprehension
This code below is a short-form method of for loop and if. The output of list comprehension is a new list.
= ['abc','abcd','bcde','bcdee','cdefg']
old_list for x in old_list if 'abc' in x] [x
## ['abc', 'abcd']
Code below is a long-version compared to list comprehension aboce.
= []
new_list = ['abc','abcd','bcde','bcdee','cdefg']
old_list for x in old_list:
if 'abc' in x:
new_list.append(x)
new_list
## ['abc', 'abcd']
3.3 Dictionaries
Dictionary is a list of index-value items.
3.3.1 Creation
Simple Dictionary
= {} ## create empty
empty_dict = { 'cats' : 2, 'dogs' : 5, 'horses':4}
animal_counts type(animal_counts)
type(empty_dict)
## <class 'dict'>
## <class 'dict'>
Dictionary with list
= ['Sax','Jack','Ann','Jeep']
horse_names = {'cats': ['Walter','Ra'],
animal_names 'dogs': ['Jim','Roy','John','Lucky','Row'],
'horses': horse_names
} animal_names
## {'cats': ['Walter', 'Ra'], 'dogs': ['Jim', 'Roy', 'John', 'Lucky', 'Row'], 'horses': ['Sax', 'Jack', 'Ann', 'Jeep']}
3.3.2 Accessor
Get All Keys
= animal_names.keys()
animal_name_keys ## it is a list
animal_name_keys for x in animal_name_keys] ## it is iterable [x
## dict_keys(['cats', 'dogs', 'horses'])
## ['cats', 'dogs', 'horses']
Get All Values
= animal_names.values()
animal_name_values ## it is a list
animal_name_values for x in animal_name_values] ## values are iterable [x
## dict_values([['Walter', 'Ra'], ['Jim', 'Roy', 'John', 'Lucky', 'Row'], ['Sax', 'Jack', 'Ann', 'Jeep']])
## [['Walter', 'Ra'], ['Jim', 'Roy', 'John', 'Lucky', 'Row'], ['Sax', 'Jack', 'Ann', 'Jeep']]
Acceess With Key
Use [ key ]
notation to get its value. However, this will return Error if key does not exist
'dogs'] animal_names[
## ['Jim', 'Roy', 'John', 'Lucky', 'Row']
For a safer approach (not to return error when key doesn’t exist), use get( key )
notation. It will return None if key does not exist
'cow') ## does not exist, return None
animal_names.get('dogs') animal_names.get(
## ['Jim', 'Roy', 'John', 'Lucky', 'Row']
3.3.3 MACD
Update/Append
Use [key]
notation to update or append the content of element. Use del
to remove a key/value pair.
= {} ## create empty
new_world 'bacteria'] = ['Ameoba','Fractona'] ## add new key/value
new_world['alien'] = ['Ali','Abu'] ## add new key/value
new_world[
new_world'bacteria'] = ['Mutu', 'Aru'] ## Update value
new_world[del new_world['alien'] ## delete key/value
new_world
## {'bacteria': ['Ameoba', 'Fractona'], 'alien': ['Ali', 'Abu']}
## {'bacteria': ['Mutu', 'Aru']}
Use clear()
to erase all elements
animal_names.clear()## now an empty dict animal_names
## {}
3.3.4 Iteration
Example below shows how to iterate over keys (.keys()
), values (.values()
) and both key/values (.items()
).
= { 'cats' : 2, 'dogs' : 5, 'horses':4}
animal_dict
for key,val in animal_dict.items()]
[ (key,val) for x in animal_dict.values()] ## values are iterable
[x for x in animal_dict.keys()] ## keys are iterable [x
## [('cats', 2), ('dogs', 5), ('horses', 4)]
## [2, 5, 4]
## ['cats', 'dogs', 'horses']
3.4 Sets
Set is unordered collection of unique items. Set is mutable
3.4.1 Creation
Set can be declared with {}
, just like list creation uses ‘[]’.
= {'a','b','c','d','a','b','e','f','g'}
myset # notice no repetition values myset
## {'a', 'b', 'g', 'f', 'c', 'd', 'e'}
Set can be created from list, and then converted back to list. This is the perfect way to make a list unique.
= ['a','b','c','d','a','b','e','f','g']
mylist = set(mylist)
myset = list(myset)
my_unique_list print (
'Original List : ', mylist,
'\nConvert to set : ', myset,
'\nConvert back to list: ', my_unique_list) # notice no repetition values
## Original List : ['a', 'b', 'c', 'd', 'a', 'b', 'e', 'f', 'g']
## Convert to set : {'g', 'c', 'd', 'a', 'b', 'f', 'e'}
## Convert back to list: ['g', 'c', 'd', 'a', 'b', 'f', 'e']
3.4.2 Operators
Membership Test
'a' in myset # is member ?
'f' not in myset # is not member ?
## True
## False
Subset Test
Subset Test : <=
Proper Subset Test : <
= {'d','g'}
mysubset <= myset mysubset
## True
Proper Subset test that the master set contain at least one element which is not in the subset
= {'b','a','d','c','e','f','g'}
mysubset print ('Is Subset : ', mysubset <= myset)
print ('Is Proper Subet : ', mysubset < myset)
## Is Subset : True
## Is Proper Subet : False
Union using |
'a','b','c'} | {'a','e','f'} {
## {'a', 'b', 'f', 'c', 'e'}
Intersection using &
Any elments that exist in both left and right set
'a','b','c','d'} & {'c','d','e','f'} {
## {'c', 'd'}
Difference using -
Remove right from left
'a','b','c','d'} - {'c','d','e','f'} {
## {'a', 'b'}