(U)Unclassified

Data Types

Data Types Overview

  • Variables
  • Numbers
  • Sequence Objects
    • Strings
    • List
    • Bytes and Bytearray
    • Tuples
    • Range
    • Buffer

Data Types Overview Cont.

  • Mapping Types
  • Set Types
  • Conversion Functions

Objectives

Data Types Objectives

Variables

Everything in Python is an Object

Objects are pieces of code that are designed to be interchangeable and reused.

type(var)

Data types are dynamic based on the variable stored. To check type, use:

							
								# python2
								x = 10
								type(x)
								# output: <type 'int'>
	
								# python3
								# output: <class 'int'>
							
						

Notice the output is <class 'int'> or <type 'int'>.... Type and class are interchangeable for our purposes. There was a time when they wern't. Once again, everything in Python is an object! We will go over type() more in meta-classes.

Multiple Assignment

Multiple assignment is allowed and types can be the same or different:

							
								# All == 100
								a = b = c = 100

								# Will only reassign variable c
								c = 200

								print ('a = {} b = {} c = {}'.format(a, b, c))
								# output: a = 100 b = 100 c = 200

								# will change all three variables
								a,b,c = 100, 'hello', {}
								print ('a = {} b = {} c = {}'.format(a, b, c))
								#output: a = 100 b = hello c = {}

							
						

Data Types: Immutable

  • Immutable objects are those that can't be changed without reassigning.
    • Such as int or str.
  • Mutable objects are those that can be changed.
    • Such as list or dict.
    • Below is a table with all types and their mutability.

Immutability

Class Description Immutable?
bool Boolean Value
int integer(arbitrary magnitude)
float floating-point number
list mutable sequence of objects
tuple immutable sequence of objects
str character string
set unordered set of distinct objects
frozenset immutable form of set class
dict associative mapping(dictionary)

Variable Labs

Lab 2A

Numbers

Prefixes convert types like binary, hex and octal into int.

  • No prefix for decimal
  • Prefix with 0b, b for binary (ex. 0b10 == 2)
  • Prefix with 0x, x for hex (ex. 0xF == 15)
  • Prefix with 0o, o for octal (ex. 0o100 == 64)

Prefix Examples:

							
									$ py -3
									>>> 0b10
									2
									
									>>> 0xF
									15
									
									>>> 0o100
									64
									
									>>> x = 0xF
									>>> type(x)
									<class 'int'>
									
									>>> x
									15
							
						

Numeric Types

  • int(integer)
    • Equivalent to C-Longs in Python 2 and non-limited in Python 3
  • Long
    • Long integers of non-limited length. Exist only in Python 2

Numeric Types

  • Float(decimal, hex, octal
    • Floating point numbers. Equivalent to C-Doubles
  • Complex
    • suffix is j or J
    • There are several built-in accessors and functions to act on complex numbers

Complex Numbers Examples:

							
									x = 1.5 + 5j
									y = 2
									z = x + y
									print(z)
									#Output: (3.5+5j)
									
									z = z + 3j
									print(z)
									#Output: (3.5+8j)
							
						

Numbers are IMMUTABLE

Numbers cannot be modified in place. Be sure to either reassign your current variable or assign the number to a new variable.

Immutable Example:

							
								$ py -3

								>>> x = 10
								>>> print(x)
								10

								>>> x = 15
								>>> print(x)
								15

								>>> x = x + 5
								>>> print(x)
								20

								>>> x + 5
								25

								>>> print(x)
								20
							
						

Bool(True or False)

Bools are a subclass of int. This was done around Python 2.2 to allow previous implementations of bools (0 and 1) to continue working… especially so with C code that utilizes Pylint_Check()

Truth Value Testing

  • The following will evaluate to false
    • False
    • zero numeric type- 0 0.0 0
    • None
    • empty sequence – ‘’ () []
    • empty mapping- {}
    • instances of user defined classes (will get into later)​

Truth Value Testing(cont.)

  • The following will evaluate to True: Everything else, not limited to but including–
    • True, 1
    • any number that is less than or greater than 0... but not 0
    • non-empty sequence/mapping, etc

Operators

  • Increment operators (x++, y--, etc) do not exist in Python
  • To increment in Python, you can use shorthand: a += 1, x -= 5, z *= 2, etc
Operator Description Example Result
+ Addition 4 + 5 9
- Subtraction 10 - 5 5
* Multiplication 4 * 2 8
/ Division 3/2 Py2(1) Py3(1.5)
// Floor Division 5.0 // 2.0 2.0
% Modulus(remainder) 4 % 2 0
** Exponentiation 4 ** 2 16
  • We are already familiar with what modulus does... it gives us the remainder.
  • Floor division on the other hand is the equivalent of dividing 2 whole numbers that should have a remainder... in Python 2.
    • Remember, Python 2 will truncate the remainder unless you specify one of the types as float.
    • Floor division will always take the floor... or the lowest number. It does not round up.

Bitwise Operators

Bitwise Operators directly manipulate bits.

Operator Description Example Result
& Binary AND 1 & 3 0001 & 0011 == 0001 (1)
| Binary OR 1 | 3 0001 | 0011 == 0011 (3)
^ Binary XOR 1 ^ 3 0001 ^ 0011 == 0010 (2)
~ Binary Ones Complement ~3 ~00000011 == 11111100
<< Binary Left Shift 1 << 3 00000001 << 3 == 00001000
>> Binary Right Shift 1 >> 3 00000001 >> 3 == 00000000

Order of Operations

Operation Precedence Extra
0 1 Anything in brackets is first
** 2 Exponentiation
-x, +x 3 N/A
*, /, %, // 4 Will evaluate left to right
+, - 5 Will Evaluate left to right

Order of Operations(cont.)

Operation Precedence Extra
<, >, <=, >=, !=, == 6 Relational Operators
Logical Not 7 N/A
Logical And 8 N/A
Logical Or 9 N/A

Type Conversion

							
								# int(x, base)
								## Returns x as 'base' integer​. 
								##'base' specifies base if x is string, otherwise optional
								### EXAMPLE 1
								x = 10.5
								int(x)
								# output: 10
								
								### EXAMPLE 2
								y = "101101"
								int(y, 2) # specifiy y as a base 2 
								# output: 45
							
						

Type Conversion(cont.)

							
								# float(x)
								## Returns x as a float
								x = 30
								float(x)
								# output: 30.0
								
								#########################
								
								# complex(real, imag)
								## Returns complex number, defaults for real/imag is 0
								
								complex(2, -3)
								# output: (2-3j)
								
								complex(2, 3)
								# output: (2+3j)
							
						

Type Conversion(cont.)

							
								# chr(x)
								## Returns string of one character for x as ASCII
								x = 10
								chr(x)
								# output: '\n'
								
								x = 10.5
								chr(int(x)) # notice what we did here? 
								# output: '\n'
								
								#########################
								
								# ord(x)
								## Returns ASCII value for x as string of one char
								ord('\n') # notice what we did here?
								# output: 10
							
						

Type Conversion(cont.)

							
								# hex(x)
								## Returns x as hex value
								hex(10)
								# output: '0xa' 
								## Notice how the output is a string, there is no hex type
								
								#########################
								
								# oct(x)
								## Returns x as octal
								oct(10)
								# output: '012'
								## Same thing here
								
								#########################
								
								# bin(x)
								## Returns x as binary
								bin(10)
								# output: '0b1010'
								## Same thing here
							
						

Numbers Labs

Lab 2b/2c

Strings

What is a sequence object?

A sequence object is a container of items accessed via index. Text strings are technically sequence objects.

Sequence Object Types:

  • String
  • Lists
  • Tuples
  • Range Objects

Each of the above support built in functions and slicing.

Sequnce Objects: Strings

Strings are immutable! They need to be reassigned. There are two independent types of strings:

  • ASCII: Default strings for Python 2
  • Unicode (UTF-8): Default strings for Python 3

To declare a string, use one of the following. There is no Pythonic way aside from keeping it as simple and clean as possible.

  • 'single quotes'
  • "double quotes"
  • ""escaped" quotes"
  • """triple quoted-multiline"""
  • r""raw" strings"

String Prefixes

  • u or U for Unicode​
  • r or R for raw string literal (ignores escape characters)​
  • b or B for byte… is ignored in Python 2 since str is bytes.​
  • A ‘u’ or ‘b’ prefix may be followed by a ‘r’ prefix.​

Yes, this stuff is old school and not very Pythonic... but it can't be helped.

Difference between ASCII and Unicode (utf-8)

  • ASCII defines 128 characters, mapped 0-127.
  • Unicode defines less than 2^21 characters, mapped 0-2^21.
  • Unicode numbers 0-128 have the same meaning as ASCII values; but do not fit into one 8-bit block of memory
  • Unicode in Python 3 utilizes utf-8 which allows for the use of multiple 8-bit blocks of memory.

Byte String vs Data String

  • Byte Strings are a sequence of bytes.
  • Python 2
    • Bytes is an alias of str
    • Bytes Type and str can be used interchangeably
  • Python 3
    • str is it's own type utilizing Unicode (utf-8)
    • bytes type in Python 3 is still a bytes object in ASCII; an array of integers

Python 2

							
								>>> x = "I am a string"
								>>> type(x)
								<type 'str'>>
								
								>>> x​
								'I am a string'
								
								>>> hex(ord(x[0]))​
								0x49
								
							
						

Python 3

							
								>>> x = 'I am a string'.encode('ASCII')​
								>>> type(x)​
								<class 'bytes'>
								
								>>> print(hex(x[0]))​
								0x49 # ASCII code for capital I​
								
								>>> x = b'I am a string' # Doing this in Python 2 makes no difference
								>>> type(x)
								<class 'bytes'>

							
						

Unicode Strings

Python 2

							
								>>> x = u"I am a unicode string"
								>>> type(x)​
								<type 'unicode'>>
								
								>>> y = unicode("Look at me! I’m a unicode string.")​
								>>> type(y)​
								<type 'unicode'>
								
								# You can use ‘…’ quotes “…” quotes or “””…””” quotes​
							
						

Python 3

							
								>>> x = 'I am a unicode string'
								>>> type(x)​
								<class 'str'>
								​
								# class str is unicode in Python 3 natively​
								# You can use ‘…’ quotes “…” quotes or “””…””” quotes​
							
						

Slicing

  • Slicing allows you to grab a substring of a string.
  • Python's indexing structure starts at 0, unless grabbing an element using a negative index.

Grabbing a specific element

							
								>>> x = "hello world"​
								>>> print(x[4]) # grabs 4th index
								o
							
						

Grab a range of elements

							
								>>> x = "hello world"
								# grabs 4th index up until, but not including the 9th index. 
								>>> print(x[4:9]) 
								o wor
							
						

Grabbing backwards from the last element

							
								>>> x = "hello world"
								>>> print(x[-3]) # grabs the 3rd to the last ELEMENT
								r
							
						
  • Slicing with negative values start at -1, not 0​. So if we have a string (x = "test"... t= -4, e = -3 s = -2 t = -1)... Thus a -2 slice will grab the 's'.
  • When slicing a range, you grab everything UPTO (not including) the second defined index number.

More String Manipulation

							
								>>> my_string = "Hello World!"
								>>> print(my_string[0]​)
								H​
								>>> print(my_string[0:5])​
								Hello​
								>>> print(my_string[6:]​)
								World!​
								
								>>> print(my_string[-6:]) # ???​
								>>> print(my_string[::2]) # ???​
								>>> print(my_string  * 2) # ???​
								>>> print(my_string + my_string) # ???​
							
						

What did you get? Try different operations to manipulate strings!

String Special Operators

Operator Description
+ Concatenation
* Repetition
[] Slice
[:] Range Slice
in Returns true if a character exists
not in Returns true if a character does not exist
% Format

User Input

There are a few ways to capture user input in Python.

  • Python 2 uses raw_input()
  • Python 3 uses input()

It is important that you use raw_input() in Python 2

  • In Python 3, input() takes user input as a string
  • Python 2 will take user input as the type presented which can lead to users implementing false bools and such.

Python 2

							
								>>> name = raw_input("What is your name? ")
								What is your name? <user input>
								>>> name
								<user input>
							
						

Python 3

							
								>>> name = input("What is your name? ")
								What is your name? <user input>
								>>> name
								<user input>
							
						

As you more than likely guessed, the user input is assigned to the variable name and stored as a string. From here, you can treat var name as any other regular string.

Useful String Methods

  • string.upper() # Outputs string as uppercase
  • string.lower() # Outputs string as lowercase
  • len(string) # Outputs string length
  • symbol.join(string/list) # Most commonly used to join list items, outputs string.​
  • string.split(symbol) # Most commonly used to split a string up into a list of items, outputs list.​

String Method Examples

							
								>>> my_string = "Hello World!”"
								>>> a = my_string.upper()​
								>>> print(a)​
								'HELLO WORLD!'​
								>>> a = my_string.lower()​
								>>> print(a) ​
								'hello world!'​
								>>> a = len(my_string)​
								>>> print(a)​
								12​
								>>> a = my_string.split(" ")​
								['Hello', 'World!']​
								>>> print(my_string)​
								'Hello World!'​
								>>> my_string = "+".join(a)​
								>>> print(my_string​)
								'Hello+World!'
							
						

Changing a character

							
								>>> my_string = "Hello World!"​
								>>> my_string[1]​
								'e'
								>>> my_string[1] = 'E'									
							
						

Join

join() combines sequential string elements by a specified _str _separator. If no separator is specified join will insert white space by default.

							
								s = "-";
								seq = ("a", "b", "c"); # This is sequence of strings.
								print(s.join( seq ))
								
								#Output: a-b-c
							
						

Split

split() will breakup a string and add the data to a string array using a defined separator.

							
								x = 'blue,red,green'
								x.split(",")
								
								['blue', 'red', 'green']
								>>>
								
								>>> a,b,c = x.split(",")
								
								>>> a
								'blue'
								
								>>> b 
								'red'
								
								>>> c
								'green'
							
						

Additional Standard Library Functionality

  • startswith, endswith​
  • find, rfind​
  • count​
  • isalnum​
  • strip​
  • capitalize​
  • title​
  • upper, lower​
  • swapcase​
  • center​
  • ljust, rjust​

Strings Labs

Lab 2D & Lab 2E

Lists

  • Lists are very similar to C arrays.
  • Lists are mutable and nestable.
  • They are not ordered
  • Lists are dynamically adjusted to fit their contents
  • Lists can be multidimensional and can contain elements of different types.
  • You can create a list using [].

List Example:

							
								>>> my_list = ['Hello World', 15, True, 'w']
								>>> nested_list = [['such', 'wow'], 5, [False, '15']]
							
						

Slicing Lists

Much like strings, you can slice lists. There are some differences though. Slicing only one element will return a substring. Whereas slicing a range of elements will return another list.

Slicing One Element:

							
								>>> my_list = ['apple', 'orange', 'cherry', 'strawberry']​
								>>> my_list[3]​
								'strawberry'​
								>>> type(my_list[3])
								<class 'str'>
								>>> nested_list = [['apple', 'orange'], ['onion', 'pepper']]​
								>>> nested_list[3] # ???​
							
						

Slicing Multiple Elements:

							
								>>> my_list[0:2]
								['apple', 'orange', 'cherry'] # outputs list
								>>> type(my_list[0:2])
								<class 'list'>
								
								
								>>> nested_list[0][1]​
								'orange'​
								>>> nested_list[0][0:2]​
								['apple', 'orange']​
								>>> nested_list[0:2][1] # ???​
							
						

Indexing Lists

index() will output the index (starting at 0) of an element that matches the index() argument. index() looks for strict matches. Overall, this is useful for finding the index of a specific item. Example below.

Index Example:

							
								>>> my_list = ['Hello World', 15, True, 'w']​
								>>> my_list.index(15)​
								1​
								>>> my_list.index('Hello')​
								Traceback (most recent call last):………​
								# index method looks for strict matches​, ValueError: 'Hello' is not in list
								# useful for finding index of a specific item
							
						

In/not in Operators

Works just like index()

In/not in Example:

							
									>>> True in my_list​
									True​
									>>> 'Hello' in my_list​
									False​
									>>> 20 not in my_list​
									True
							
						

Modifying Lists

Rememeber, lists are MUTABLE! This simply means we can modify it in place via appending, removing, combining, etc.

Updating Lists:

  • append()
    • Adds on to the end of the list
  • insert(i,x)
    • Inserts object x into the list at offset index i
  • sort, sorted()
    • Sorts list alphabetically
    • Both accept a reverse parameter with a Boolean value​
    • Both also accept a key parameter that specifies a function to be called on each list element prior to making comparisons.

Modifying Lists Examples:

							
								>>> my_list = [1,2,3,4,5]​
								>>> my_list.append(6)​
								[1, 2, 3, 4, 5, 6]​
								
								>>> my_list[0] = 99​
								>>> my_list​
								[99, 2, 3, 4, 5, 6]​
								
								>>> my_list.insert(0, 1)​
								>>> my_list​
								[1, 99, 2, 3, 4, 5, 6]​
								
								>>> messy_list = [2,1,4,5,3,5,100,222,44]​
								>>> sorted(messy_list)​
								# ??????​
								>>> print(messy_list)
								
								>>> messy_list.sort()
								# ??????
								>>> print(messy_list)
								
								>>> messy_list.sort(reverse=True)​
								>>> messy_list​
								# ??????​
								>>> print(messy_list)
							
						

Combining Lists

  • extend()
    • concatenates the first list with another list or iterable.​
  • +=
    • also concatenates the first list with another list or iterable.​​

Combining Lists Example:

							
								>>> rally_cars = ['Subaru', 'Ford’]​
								>>> rally_cars.extend(['Mini', 'Audi'])​
								>>> rally_cars​
								['Subaru', 'Ford', 'Mini', 'Audi']​

								>>> rally_cars += ['Peugeot', 'MG Metro']​
								>>> rally_cars​
								['Subaru', 'Ford', 'Mini', 'Audi', 'Peugeot', 'MG Metro']​
							
						

Removing List Elements

  • list.remove()
    • Removes the first value that matches x.​​
  • del list[x]​
    • Removes a specific index.​​
  • list.pop(x)​
    • Removes the specific index and returns the removed element.​

Removing Lists Example:

							
								# remove()​
								>>> my_list = [1,2,3,3,4,5]​
								>>> my_list.remove(3)​
								>>> my_list​
								[1, 2, 3, 4, 5]​
								
								# del​
								>>> del my_list[2]​
								>>> my_list​
								[1, 2, 4, 5]​
								
								# pop()​
								>>> my_list.pop(1)​
								2 # value popped​
								>>> my_list​
								[1, 4, 5]
							
						

Map, Filter, Reduce

Map() applies a function to all the items in an input_list.

							
								map(function_to_apply, list_of_inputs)
							
						

Map Example:

							
								items = [1, 2, 3, 4, 5]
								squared = []
								for i in items:
									squared.append(i**2)
							
						

map() allows us to implement this in a much simpler way

							
								items = [1, 2, 3, 4, 5]
								squared = list(map(lambda x: x**2, items))
							
						

Another Map Example:

Don't fret over what lambda's are just yet. Just know they are condensed functions for now

							
								def multiply(x):
									return (x*x)
								def add(x):
									return (x+x)
								
								funcs = [multiply, add]
								for i in range(5):
									value = list(map(lambda x: x(i), funcs))
									print(value)
								
								# Output:
								# [0, 0]
								# [1, 2]
								# [4, 4]
								# [9, 6]
								# [16, 8]
							
						

Filter:

filter() - creates a list of elements for which a function returns true.

							
									number_list = range(-5, 5)
									less_than_zero = list(filter(lambda x: x < 0, number_list))
									print(less_than_zero)
									
									# Output: [-5, -4, -3, -2, -1]
							
						

The filter resembles a for loop but it is a builtin function and faster.

Reduce:

reduce() - performs some computation on a list and returns the result. It applies a rolling computation to sequential pairs of values in a list.

							
									number_list = range(-5, 5)
									less_than_zero = list(filter(lambda x: x < 0, number_list))
									print(less_than_zero)
									
									# Output: [-5, -4, -3, -2, -1]
							
						

The filter resembles a for loop but it is a builtin function and faster.

Reduce Example:

Computing the product of a list of integers

							
								product = 1
								list = [1, 2, 3, 4]
								for num in list:
									product = product * num

								# product = 24
							
						

Using reduce:

							
									from functools import reduce # we will cover this later

									product = reduce((lambda x, y: x * y), [1, 2, 3, 4])
									
									# Output: 24
							
						

List Labs

Lab 2F

Bytes and Bytearray

Bytes()

  • Python 2 strings are bytes naturally whereas Python 3 is unicode and needs to be defined as bytes when you want to use bytes type.
  • There are a couple ways to turn Python 3 strings into bytes, this functionality is backwards compatible with Python 2.
  • It's highly recommended you define Python 2 strings the same way if you are going to be modifying the bytes.
							
								# Method 1 (shortest)
								>>> x = b'hello world'
								>>> print(x[1])
								101 # ASCII dec value
								
								# Method 2 (clean)
								>>> x = 'hello world'
								>>> y = bytes(x, 'ascii')
								>>> print(y)
								b'hello world'
								>>> print(y[1])
								101 # ASCII dec value
								
								# python 2
								>>> x = 'hello world'
								>>> print ord(x[1]) 
								# ord is the inverse of chr()... returns int representing the unicode code point of the argument
								101 # Unicode dec value
							
						

This can go both ways. We can convert these integer representations back into Unicode or ASCII strings.

							
								# Python 2 back to ascii string
								>>> x = ord('e')
								>>> x
								101
								>>> y = chr(x)
								>>> y
								'e'
								# convert y into a unicode string (this only works in Python 2 because unicode is default in Python 3)
								>>> y = unichr(x)
								>>> y
								u'e'
								
								# Python 3 back to native unicode string
								>>> x = ord('e')
								>>> x
								101
								>>> y = chr(x)
								>>> y
								'e'
								# y is now a unicode string... but how do we turn it into a byte/ascii string?
								>>> y = bytes(y, 'ascii')
								>>> y
								b'e'
								# Now y is a python 2 str type... bytes/ascii
									
							
						

Bytearray()

  • Bytearray() is a mutable sequence of integers in range of 0 <= x < 256; available in Python 2.6 and later​.
  • Byte Arrays are useful when you need to modify individual bytes in a sequence.

Python 2

							
								>>> x = "I am a string"
								>>> b = bytearray()​
								>>> b.extend(x) 
								# This was done on purpose to show it is mutable 
								# You can pass the str directly into the bytearray() function to cut 2 lines
								>>> b​
								bytearray(b'I am a string')​
								>>> b[2]​
								97 # decimal for 'a' char​
								>>> b[2] = 85​ # Modifying a byte
								>>> b​
								bytearray(b'I Um a string')​ # notice b did change without reassignment
							
						

Python 3

							
								>>> b = bytearray(b"I am a string")​
								>>> b​
								bytearray(b'I am a string')​
								>>> b[2]​
								97 # decimal for 'a' char​
								>>> b[2] = 85​
								b​
								bytearray(b'I Um a string')
							
						

Bytes and Byte Array Labs

Lab 2G

Tuples, Range & Buffer

Tuples

  • Tuples are very similar to lists. The major difference is that tuples are IMMUTABLE!
  • You cannot modify it's contents without reassigning.
  • The length of tuples are set in stone.
  • Parentheses (round brackets like these) are commonly used to declare tuples.
  • The parentheses are not required! You can declare tuples by just using commas.
							
								# common method to declare tuples
								>>> someTuple = (1,2,3,4,5)
								# alternative method
								>>> neatTuple = 1,2,3,4,5
								
								>>> print neatTuple
								(1, 2, 3, 4, 5)
								
								# What does the below do?
								>>> del someTuple[2]
							
						

Why Use Tuples?

Tuples are still sequence objects. You can still:

  • Implement all common sequence operations​
  • Slice​
  • Index​

Useful for:

  • Returning multiple results from functions​
  • Since they are immutable, they can be used as keys for a dictionary.​

range()

range() represents an immutable iterable object that always takes the small and same amount of memory irrespective of the size of range because it only stores start, stop, and step values and calculates values as needed.

  • Python 3's range() is essentially a combination of Python 2's range() and xrange()
  • Syntax

    range(stop) range(start, stop,[ step])

    start: Required when full syntax is used. An integer specifying start value for the range.

    stop: Required. The boundary value for the range.

    step: Optional. Step value.

    							
    								>>> range(4)
    								range(0,4)
    								
    								# if we want to see what is contained within our range
    								>>> list(range(4))
    								[0, 1, 2, 3]
    								
    								>>> list(range(2,6))
    								[2, 3, 4, 5]
    								
    								>>> list(range(0,50,5))
    								[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]
    								
    								>>> list(range(4,12,3))
    								# ???
    								
    								>>> list(range(0,-10,-2))
    								# ???
    							
    						

    We will cover range() more in depth and use it a lot more when we get to loops.

    xrange()

    xrange() is from Python 2 and is similar to range(), returns xrange object (sequence object) instead of list.

    								
    									>>> for i in xrange(10):
    									>>>    print i
    									0
    									1
    									2
    									3
    									4
    									5
    									6
    									7
    									8
    									9
    									
    									# Only even numbers
    									>>> for i in xrange(2, 10, 2):
    									>>>     print i
    									2
    									4
    									6
    									8
    									
    									# Negative numbers
    									>>> for i in xrange(-1, -10, -1):
    									>>>     print i
    									-1
    									-2
    									-3
    									-4
    									-5
    									-6
    									-7
    									-8
    									-9
    								
    							

    Buffer (memoryview)

    Buffer (memoryview) is useful if you don’t want to or can’t hold multiple copies of data in memory. It can also be lightning fast since it's not copying the data. Buffer (or memoryview) essentially expose (by reference) raw byte arrays to other Python objects. That means the argument passed must be in bytes (ints representing bytes).

    Example:

    							
    								# Python 2
    								>>> x = b'100'
    								>>> buffer(x)
    								<read-only buffer for 0x10b1acc60, size -1, offset 0 at 0x10b1a9930>
    								
    								# Python 3
    								>>> x = b'100'
    								>>> memoryview(x)
    								<memory at 0x1040b1948>
    							
    						

    Practical example

    							
    								import time
    								for n in (100000, 200000, 300000, 400000):
    									data = 'x'*n                            # set data = 'x'*n (if n were 5, xxxxxx)
    									start = time.time()                     # start a timer
    									b = data                                # set b = data
    									while b:                                # remove one x and reasign to b, continue until 0
    										b = b[1:]
    									print 'bytes', n, time.time()-start     # stop time, print out time it took to do operation
    								
    								
    								# Same thing here, except we use memoryview instead
    								for n in (100000, 200000, 300000, 400000):
    									data = 'x'*n
    									start = time.time()
    									b = memoryview(data)
    									while b:
    										b = b[1:]
    									print 'memoryview', n, time.time()-start
    							
    						

    Dictionaries and Sets

    Dictionary

    • Dictionaries are mutable objects and consist of key-value mappings. (ex: {key: ‘value’, key: ‘value’} ).
    • They are initialized using the curly-brackets {}.
    • Dictionaries are not ordered and support all value types.
    							
    								>>> my_dict = {} # create empty dictionary​
    								>>> my_dict['one'] = 1 # add item to the dictionary​
    								>>> print my_dict
    								{'one': 1}​
    								
    								# OR
    								>>> my_dict = {'one' : 1} #create a dictionary with an item​
    								>>> print my_dict​
    								{'one': 1}​
    								​
    								>>> my_dict['two'] = 2 # add item to the dictionary​
    								>>> print my_dict​
    								{'one': 1, 'two': 2}​
    								
    								# Grabbing by key
    								>>> new_dict = {'key1':'value1','key2':'value2','key3':'value3'}
    								>>> print new_dict['key2']
    								'value2'
    							
    						

    Multi-Dimensional Dictionaries

    Just like lists... Dictionaries can be nested as well to create a multi-dimensional dictionary.

    							
    								# Dict -> Dict
    								>>> my_dict = {'key1':{'nestedkey1':{'subnestedkey1':'subnestedValue'}}}
    								>>> print my_dict
    								{'key1':{'nestedkey1':{'subnestedkey1':'subnestedValue'}}}
    								
    								# Grab key 1's value
    								>>> print my_dict['key1']
    								{'nestedkey1': {'subnestedkey1': 'subnestedValue'}}
    								
    								# Grab nested key 1's value
    								>>> print my_dict['key1']['nestedkey1']
    								{'subnestedkey1': 'subnestedValue'}
    								
    								# Grab subnested key 1's value
    								>>> print my_dict['key1']['nestedkey1']['subnestedkey1']
    								subnestedValue
    							
    						

    Common Dictionary Operations

    							
    								>>> d[i] = y # value of I is replaced by y​
    								>>> d.keys() # grabs all keys
    								>>> d.values() # grabs all values
    								>>> d.clear() # removes all items​
    								>>> d.copy() # creates a shallow copy of dict_x​
    								>>> d.fromkeys(S[,v]) # new dict from key, values​
    								>>> d.get(k[,v]) # returns dict_x[k] or v​
    								>>> d.items() # list of tuples of (key,value) pairs​
    								>>> d.iteritems() # iterator over (key,value) items​
    								>>> d.iterkeys() # iterator over keys of d​
    								>>> d.itervalues() # iterator over values of d​
    								>>> d.pop(k[,v]) # remove/return specified (key,value)​
    								>>> d.popitem() # remove/return arbitrary (key,value)​
    								>>> d.update(E, **F) # update d with (key,values) from E
    							
    						

    Set and Frozenset

    A set is an unordered collection of unique elements. Sets are mutable but contain no hash value-- so they can't be used as dict keys or as an element of another set.

    Set Example

    							
    								>>> new_set = set() # create an empty set​
    								>>> new_set = {0, 1, 1, 1, 2, 3, 4} ​
    								>>> new_set​
    								{0, 1, 2, 3, 4}​
    								
    								>>> new_set.add(5) # Add new key to set​
    								>>> new_set​
    								{0, 1, 2, 3, 4, 5}​
    								
    								>>> x_set = set("This is a set")​
    								>>> x_set​
    								{'s', 't', 'e', 'h', 'I', ' ', 'T', 'a'}​
    								
    								>>> another_set = set(['Ford', 'Chevy', 'Dodge', 105, 555])​
    								{'Chevy', 105, 155, 'Ford', 'Dodge'} # many ways to create set​
    							
    						

    Frozenset

    Frozensets are identical to sets aside from the fact that they are immutable. Since frozensets are immutable, they are hashable as well. So they can be used as a dict key or element of another set.

    Frozenset Example

    							
    								>>> new_set = frozenset([1,2,2,2,3,4])# create an frozenset​
    								>>> new_set​
    								frozenset({1, 2, 3, 4})​
    								>>> new_set.add(5)​
    								.......AttributeError: ‘frozenset’ object has no attribute ‘add’​
    								# Doesn't work since Frozenset is immutable
    								
    								# Many… many ways to create frozenset as well. ​
    							
    						

    Common Set Operations

    Some do not apply to Frozenset

    							
    								>>> s.issubset(t) # test if elements in s are in t​
    								>>> s.issuperset(t) # test if elements in t are in s​
    								>>> s.union(t) # new set with elements of t and s​
    								>>> s.intersection(t) # new set with common elements​
    								>>> s.difference(t) # new set with elements in s but not t​
    								>>> s.symmetric_difference # xor​
    								>>> s.copy() # new shallow copy of s​
    								>>> s.update(t) # return set s with elements from t​
    								>>> s.intersection_update(t)​
    								>>> s.difference_update(t)​
    								>>> s.symmetric_difference_update(t)​
    								>>> s.add(x) # add x to set s​
    								>>> s.remove(x) # remove x from set s​
    								>>> s.discard(x) # remove x from set s if present​
    								>>> s.pop() # remove arbitrary item​
    								>>> s.clear() #remove all elements from set a​
    							
    						

    Additional Functionality

    Conversion Functions

    Below are some functions to convert a variable to another type.

    							
    								>>> int()​
    								>>> long()​
    								>>> float()​
    								>>> complex()​
    								>>> str()​
    								>>> repr()​
    								>>> eval()​
    								>>> tuple()​
    								>>> list()​
    								>>> set()​
    								>>> dict()​
    								>>> frozenset()​
    								>>> chr()​
    								>>> unichr()​
    								>>> ord()​
    								>>> hex()​
    								>>> oct()​
    								>>> bin()
    							
    						

    Import Sys

    Sys is a large module from the Standard Library that contains very useful code and functionality. We will get into what modules are and how to import and such later in the course. For now, we are going to focus on one function from the module.

    sys.getsizeof(object) --gets the size of the object passed in bytes. As you can imagine, this is going to be very helpful in streamlining your code.

    Example:

    							
    								>>> import sys​
    								>>> x = 40​
    								>>> sys.getsizeof(x)​
    								12
    							
    						

    Documentation:

    • https://docs.python.org/2.7/library/sys.html​
    • https://docs.python.org/3.6/library/sys.html

    Dictionaries and Sets Labs

    Lab 2H

    Questions?