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.
Benefits of tuple against List are: - Faster than list - Protects your data against accidental change - Can be used as key in dictionaries, list can’t
3.1.3 Duplicating
Use normal assignment = to duplicate. Reference of the memory address is copied. Data is actually not duplicated in memory.
original = (1,2,3,4,5)
copy_test = original
print(original)#:> (1, 2, 3, 4, 5)
print(copy_test)#:> (1, 2, 3, 4, 5)
The copy and original has the same memory location.
print('Original ID: ', id(original))#:> Original ID: 139903753534832
print('Copy ID: ', id(copy_test))#:> Copy ID: 139903753534832
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 Creating List
3.2.2 Accessing Items
Access specific index number
food = ['bread', 'noodle', 'rice', 'biscuit','jelly','cake']
print (food[2]) # 3rd item#:> rice
print (food[-1]) # last item#:> cake
Access range of indexes
print (food[:4]) # first 3 items#:> ['bread', 'noodle', 'rice', 'biscuit']
print (food[-3:]) # last 3 items#:> ['biscuit', 'jelly', 'cake']
print (food[1:5]) # item 1 to 4#:> ['noodle', 'rice', 'biscuit', 'jelly']
print (food[5:2:-1]) # item 3 to 5, reverse order#:> ['cake', 'jelly', 'biscuit']
print (food[::-1]) # reverse order#:> ['cake', 'jelly', 'biscuit', 'rice', 'noodle', 'bread']
3.2.3 Methods
3.2.3.1 Remove Item(s)
Removal of non-existance item will result in error
Search and remove first matching item
food = list(['bread', 'noodle', 'rice', 'biscuit','jelly','cake','noodle'])
food.remove('noodle')
print (food)#:> ['bread', 'rice', 'biscuit', 'jelly', 'cake', 'noodle']
Remove last item
food.pop()#:> 'noodle'
print (food)#:> ['bread', 'rice', 'biscuit', 'jelly', 'cake']
Remove item at specific position
food.pop(1) # counter start from 0#:> 'rice'
print(food)#:> ['bread', 'biscuit', 'jelly', 'cake']
food.remove('jelly')
print(food)#:> ['bread', 'biscuit', 'cake']
3.2.3.2 Appending Item (s)
Append One Item
food.append('jelly')
print (food)#:> ['bread', 'biscuit', 'cake', 'jelly']
Append Multiple Items extend() will expand the list/tupple argument and append as multiple items
food.extend(['nand','puff'])
print (food)#:> ['bread', 'biscuit', 'cake', 'jelly', 'nand', 'puff']
3.2.3.3 Other Methods
Reversing the order of the items
food.reverse()
food#:> ['puff', 'nand', 'jelly', 'cake', 'biscuit', 'bread']
Locating the Index Number of An Item
food.index('biscuit')#:> 4
Count occurance
test = ['a','a','a','b','c']
test.count('a')#:> 3
Sorting The Order of Items
food.sort()
print (food)#:> ['biscuit', 'bread', 'cake', 'jelly', 'nand', 'puff']
3.2.5 List is Mutable
The reference of list variable won’t change after adding/removing its item
food = ['cake','jelly','roti','noodle']
print ('food : ',id(food))#:> food : 139903753597728
food += ['salad','chicken']
print ('food : ',id(food))#:> food : 139903753597728
A function is actually an object, which reference never change, hence mutable
def spam (elem, some_list=['a','b']):
some_list.append(elem)
return some_list
print (spam(1,['x']))#:> ['x', 1]
print (spam(2)) ## second parameter is not passed#:> ['a', 'b', 2]
print (spam(3)) ## notice the default was remembered#:> ['a', 'b', 2, 3]
3.2.6 Duplicate or Reference
Use = : It just copy the refernce. IDs are similar
original = [1,2,3,4,5]
copy_test = original
print('Original ID: ', id(original))#:> Original ID: 139903753598368
print('Copy ID: ', id(copy_test)) #:> Copy ID: 139903753598368
original[0]=999 ## change original
print(original)#:> [999, 2, 3, 4, 5]
print(copy_test) ## copy affected#:> [999, 2, 3, 4, 5]
Duplicate A List Object with copy(). Resulting IDs are different
original = [1,2,3,4,5]
copy_test = original.copy()
print(original)#:> [1, 2, 3, 4, 5]
print(copy_test)#:> [1, 2, 3, 4, 5]
print('Original ID: ', id(original))#:> Original ID: 139903753608240
print('Copy ID: ', id(copy_test))#:> Copy ID: 139903914202208
original[0] = 999 ## change original
print(original) #:> [999, 2, 3, 4, 5]
print(copy_test) ## copy not affected#:> [1, 2, 3, 4, 5]
Passing To Function As Reference
def func(x):
print (x)
print('ID in Function: ', id(x))
x.append(6) ## modify the refrence
my_list = [1,2,3,4,5]
print('ID outside Function: ', id(my_list))#:> ID outside Function: 139903914209360
func(my_list) ## call the function, pass the reference#:> [1, 2, 3, 4, 5]
#:> ID in Function: 139903914209360
print(my_list) ## content was altered#:> [1, 2, 3, 4, 5, 6]
3.2.7 List Is Iterable
3.2.7.1 For Loop
s = ['abc','abcd','bcde','bcdee','cdefg']
for x in s:
if 'abc' in x:
print (x)#:> abc
#:> abcd
3.2.7.2 List Comprehension
This code below is a shorform method of for loop and if.
old_list = ['abc','abcd','bcde','bcdee','cdefg']
[x for x in old_list if 'abc' in x]#:> ['abc', 'abcd']
Compare to traditional version of code below:
new_list = []
old_list = ['abc','abcd','bcde','bcdee','cdefg']
for x in old_list:
if 'abc' in x:
new_list.append(x)
print( new_list )#:> ['abc', 'abcd']
3.3 Dictionaries
Dictionary is a list of index-value items.
3.3.1 Creating dict
3.3.1.1 From Literals
Simple Dictionary
animal_counts = { 'cats' : 2, 'dogs' : 5, 'horses':4}
print (animal_counts)#:> {'cats': 2, 'dogs': 5, 'horses': 4}
print( type(animal_counts) )#:> <class 'dict'>
Dictionary with list
animal_names = {'cats': ['Walter','Ra'],
'dogs': ['Jim','Roy','John','Lucky','Row'],
'horses': ['Sax','Jack','Ann','Jeep']
}
animal_names#:> {'cats': ['Walter', 'Ra'], 'dogs': ['Jim', 'Roy', 'John', 'Lucky', 'Row'], 'horses': ['Sax', 'Jack', 'Ann', 'Jeep']}
3.3.1.2 From Variables
cat_names = ['Walter','Ra','Jim']
dog_names = ['Jim','Roy','John','Lucky','Row']
horse_names= ['Sax','Jack','Ann','Jeep']
animal_names = {'cats': cat_names, 'dogs': dog_names, 'horses': horse_names}
animal_names#:> {'cats': ['Walter', 'Ra', 'Jim'], 'dogs': ['Jim', 'Roy', 'John', 'Lucky', 'Row'], 'horses': ['Sax', 'Jack', 'Ann', 'Jeep']}
3.3.2 Accessing dict
3.3.2.1 Get All Keys
print (animal_names.keys())#:> dict_keys(['cats', 'dogs', 'horses'])
print (sorted(animal_names.keys()))#:> ['cats', 'dogs', 'horses']
3.3.2.2 Get All Values
print (animal_names.values())#:> dict_values([['Walter', 'Ra', 'Jim'], ['Jim', 'Roy', 'John', 'Lucky', 'Row'], ['Sax', 'Jack', 'Ann', 'Jeep']])
print (sorted(animal_names.values()))#:> [['Jim', 'Roy', 'John', 'Lucky', 'Row'], ['Sax', 'Jack', 'Ann', 'Jeep'], ['Walter', 'Ra', 'Jim']]
3.3.2.3 Access value with Specific Key
Use [ key ] notation. However, this will return Error if key does not exist
animal_names['dogs']#:> ['Jim', 'Roy', 'John', 'Lucky', 'Row']
Use get( key ) notation. will return None if key does not exist
print (animal_counts.get('cow'))#:> None
3.3.3 Dict Is Mutable
3.3.3.1 Update/Append
Use [key] notation to update o append the content of element.
animal_names['dogs'] = ['Ali','Abu','Bakar']
animal_names#:> {'cats': ['Walter', 'Ra', 'Jim'], 'dogs': ['Ali', 'Abu', 'Bakar'], 'horses': ['Sax', 'Jack', 'Ann', 'Jeep']}
Use clear() to erase all elements
animal_names.clear()3.4 Sets
Set is unordered collection of unique items. Set is mutable
3.4.1 Creation
Set can be declared with {}, unlike list creation uses ‘[].’
myset = {'a','b','c','d','a','b','e','f','g'}
print (myset) # notice no repetition values#:> {'c', 'e', 'b', 'f', 'g', 'd', 'a'}
Set can be created from list, and then converted back to list
mylist = ['a','b','c','d','a','b','e','f','g']
myset = set(mylist)
my_unique_list = list(myset)
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 : {'c', 'e', 'b', 'f', 'g', 'd', 'a'}
#:> Convert back to list: ['c', 'e', 'b', 'f', 'g', 'd', 'a']
3.4.2 Membership Test
print ('a' in myset) # is member ?#:> True
print ('f' not in myset) # is not member ?#:> False
3.4.3 Subset Test
Subset Test : <=
Proper Subset Test : <
mysubset = {'d','g'}
mysubset <= myset#:> True
Proper Subset test that the master set contain at least one element which is not in the subset
mysubset = {'b','a','d','c','e','f','g'}
print ('Is Subset : ', mysubset <= myset)#:> Is Subset : True
print ('Is Proper Subet : ', mysubset < myset)#:> Is Proper Subet : False
3.5 range
range(X) generates sequence of integer object
range (lower_bound, upper_bound, step_size)
# lower bound is optional, default = 0
# upper bound is not included in result
# step is optional, default = 1
Use list() to convert in order to view actual sequence of data
r = range(10) # default lower bound =0, step =1
print (type (r))#:> <class 'range'>
print (r)#:> range(0, 10)
print (list(r))#:> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
More Examples
print (list(range(2,8))) # step not specified, default 1#:> [2, 3, 4, 5, 6, 7]
print ('Odds Number : ' , list(range(1,10,2))) # generate odds number#:> Odds Number : [1, 3, 5, 7, 9]