06 SetTupleDictionaryYield-1
06 SetTupleDictionaryYield-1
Hyeong-Seok Ko
Seoul National University
Dept. of Electrical and Computer Engineering
Contents
• Sets
• Tuples
• Dictionaries
• Yield and Iterator
Sets
Set
• An unordered collections of unique elements
– Does not support indexing, or other sequence-based operation
– Sets cannot contain mutable elements (such as lists or dictionaries)
S1 = {1, 2, 5, "hello"}
print(S1)
print(S2)
for item in S2 :
print(item, end=" ")
print()
print(1) print(1,end='')
print(2) print(2, end='')
print(3) print(3)
1 123
2
3 print(1,end=' ')
print(2, end=' ')
print(3)
1 2 3
• The end parameter defines the line terminator for the print function.
• By default, end = “new line”, i.e., “\n"
• By having end = ‘ ‘ or ‘ ‘, you can avoid new line.
Sep Parameter for print()
>>> print(1, 2, 3)
1 2 3
>>> print('1\n2\n3')
1
2
3
>>> print(1, 2, 3, sep='\n')
1
2
3
• The sep argument defines the separator between the arguments to print.
• sep='\n' tells, after printing each item, to put the separation character.
• By default, sep = “space” which is known as “soft spacing”.
• You can also use \t, \\, etc. as sep.
Useful Functions/Operations for Set
• Basic set operations
– Intersection & A = {1, 2, 3}
B = {2, 3, 4}
– Union | print(A&B)
– Difference - print(A|B)
• Practice more in the following 2 pages print(A-B)
{2, 3}
{1, 2, 3, 4}
{1}
Type&Run: add, update, discard, clear, remove,…
Source code Result
s1 = set() set() empty set
print(s1) {1, 3}
s1.add(1) {1, 3, 5, 7, 9}
s1.add(3)
print(s1) {1, 3, 5, 7, 9}
s1.update({3, 5, 7, 9}) adds multiple elements {1, 5, 7, 9}
print(s1, '\n') {1, 5, 7, 9}
{5, 7, 9}
s1_copy = s1.copy()
print(s1_copy) False
s1_copy.discard(3) False True
print(s1_copy) True False
s1_copy.discard(2)
#s1_copy.remove(2) if not present, produces error {5, 7, 9}
print(s1_copy) set()
s1_copy.pop() randomly removes one element
print(s1_copy, '\n')
print(s1.isdisjoint(s1_copy))
print(s1.issubset(s1_copy), s1_copy.issubset(s1))
print(s1.issuperset(s1_copy), s1_copy.issuperset(s1), '\n')
print(s1_copy)
s1_copy.clear()
print(s1_copy)
Type&Run: difference, intersection, union
Source code Result
s1 = {1, 3, 5, 7, 9} {1, 3, 5, 7, 9} {8, 2, 4, 6} {1, 3}
s2 = {2, 4, 6, 8} {1, 3, 5, 7, 9} {9, 5, 7} {9, 5, 7}
s3 = {1, 3} {1, 3, 5, 7, 9} {9, 5, 7} {5, 7, 9}
print()
print(s1 ^ s2, s1 ^ s3, s1 ^ s2 ^ s3) # s1^s2 = (s1-s2)|(s2-s1)
print(s1.symmetric_difference(s2), s1.symmetric_difference(s3))
#s1.symmetric_difference_update(s2)
#s1.symmetric_difference_update(s3)
print()
print(s1 | s2, s1 | s3, '\n', s1 | s2 | s3)
print(s1.union(s2), s1.union(s3), '\n', s1.union(s2, s3))
Tuples
Tuple ["banana",
42 3.14159 "hello"
"apple"]
<class 'tuple'>
42 3.14159 hello
42
Error
More about Tuple
print('Repeating')
print(2*('a', 'b', 'cd'))
print(('a', 'b', 'cd')*3)
Type&Run: finding out the index
# set to list
S = {'I', 'am', 'a', 'set'}
print(list(S))
Dictionaries
Dictionary
• An unordered set of key:value pairs
– Indexed by the keys
– The keys should be unique within the dictionary
– The values are mutable, but keys are immutable
Source code
Result
{0: 1, 1: 1, 2: 1}
['', 'a', 'aa', '', 'p', 'pp', '', 'p', 'pp', '', 'l', 'll', '', 'e', 'ee']
{0: 'pp', 1: 'pp'}
Type&Run: Dictionary Basics
Source code
D = {'21-123':(1, 2), (2, 1):3.1, 4:True, 2.1:'abc' }
Result
for item in D.items(): ('21-123', (1, 2)), ((2, 1), 3.1), (4, True), (2.1, 'abc'),
print(item , end = ', ') 21-123:(1, 2), (2, 1):3.1, 4:True, 2.1:abc,
print() 21-123, (2, 1), 4, 2.1,
for k, v in D.items(): (1, 2), 3.1, True, abc,
print(k, v, sep = ':', end = ', ') ?
print() True
for k in D.keys():
print(k , end = ', ') {'21-123': (1, 2), (2, 1): 3.1, 4: True, 2.1: 'abc'}
print() {'21-123': (1, 2), (2, 1): 3.1, 4: False, 2.1: 'abc', 0: 45}
for v in D.values(): {(2, 1): 3.1, 4: False, 2.1: 'abc', 0: 45}
print(v , end = ', ') {(2, 1): 3.1, 4: False, 2.1: 'abc'}
print()
print(D.get((1, 2), '?')) abc
print(D.get(4, '?'), '\n') True
{(2, 1): 3.1, 4: False, 2.1: 'abc', 5: True}
D_copy = D.copy() {}
print(D_copy)
D_copy.update({4:False, 0:45}) modify or add
print(D_copy)
D_copy.pop('21-123')
print(D_copy)
D_copy.popitem() # deletes the lastly inserted item
print(D_copy, '\n')
D = dict([(1, 1), (5, 25), (0, 0), (3, 9), (7, 49), (9, 81)])
print(D)
print(len(D))
print(sorted(D), sorted(D, reverse=True)) # with the key…
Type&Run: del statement (int, float, bool, string)
print(L_copy)
for item in L_copy:
del item does not delete
print(L_copy)
for _ in range(len(L_copy)):
del L_copy[0]
#del L_copy[:]
print(L_copy, '\n')
print(T)
#del T[0] # error
del T
#print(T) # error
Type&Run: del statement (set, dictionary)
print(D)
del D[1]
print(D)
del D[3, 4]
# same as del D[(3, 4)]
print(D)
del D
#print(D) # error
Home Exercise: Using Dictionary for SpMV,
Sparse Matrix and Vector multiplication
• When only a few percent of the matrix is non-zero, we say the matrix is sparse.
– In most real world problems, matrices are sparse.
• The sparse matrix uses specialized matrix storage
– To save the storage, it stores only non-zero elements
• The sparse matrix can be implemented using dictionary.
– The key can be string or tuple as follows:
mat = {}
mat["nr"] = 5 # Replace this with input()
mat["nc"] = 5
for _ in range(10): # produce about 10 nonzero elements
mat[(randint(0,5), randint(0,5))] = randint(1,2)
printMatrix(mat)
vec = []
for i in range(5): # produce the vector
vec[i] = randint(0,3)
print(vec)
vec2 = SpMV(mat, vec)
print(vec2)
2 0 0 1 0
0 0 0 2 0
0 0 0 0 0
0 0 1 1 0
1 0 0 0 0
[0, 1, 3, 3, 1]
[3, 6, 0, 6, 0]
You can Use the Following Functions
def printMatrix(m):
for i in range(m["nr"]):
for j in range(m["nc"]):
print(m.get((i,j),0), end = " ")
print()
• The yield statement suspends function’s execution and sends a value back to the caller, but
retains enough state to enable function to resume where it is left off.
• When resumed, the function continues execution immediately after the last yield run.
• The terms “generator” and “driver”
– If the body of a function contains yield, that function is called a generator.
– If a part of the code calls a generator, it is called a driver.
• A typical usage of the generator from the for loop:
def n_seq(n):
# the generator code
num = 0
def generator1(): 0
1 while num < n:
yield 1 in generator
2 yield num * 2
yield 2 6
3 print("in generator")
yield 3 in generator
num += 1
# the driver code 12
for value in generator1(): in generator
for item in n_seq(3):
print(value)
print(item * 3)
Generator returns an Iterator
x = n_seq(2)
print(x)
print(next(x))
print(next(x))
print(next(x))
x = [0, 1, 2] [0, 1, 2]
<list_iterator object at 0x036DA640>
print(x) 0
1
# print(next(x)) # error
# print(next(x)) # error
y = iter(x)
print(y)
print(next(y))
print(next(y))
def n_seq2(n):
num, nums = 0, []
while num < n:
nums.append(num)
num += 1
return nums Needs memory for storing this list
print(sum(n_seq2(11))) 55
Summing an Iterator
• sum(iterable, start)
– iterable: A generator is an iterable, so can come at this place.
– start (optional): This value is added to the sum. The default value of start is 0 (if omitted)
def n_seq(n):
num = 0
while num < n:
yield num
num += 1
print(sum(n_seq(11))) 55
x = (i for i in range(11))
print(x)
print(next(x))
print(sum(x))
y = [i for i in range(11)]
print(y)
# print(next(y)) produces error
print(sum(y))
• Set comprehension
{expression for item in iterable if condition}
• Dictionary comprehension
{key:value for item in iterable if condition}
• Generator expression
(expression for item in iterable if condition)
Type&Run: various comprehensions
Source code
lComprehension = [i for i in range(10) if i % 2 == 0]
sComprehension = {i for i in range(10) if i % 2 == 1}
dComprehension = {i:2*i for i in range(5) if i % 2 == 0}
gExpression = (i for i in range(10) if i % 2 == 0)
print(lComprehension)
print(sComprehension)
print(dComprehension)
print(gExpression)
Result
[0, 2, 4, 6, 8]
{1, 3, 5, 7, 9}
{0: 0, 2: 4, 4: 8}
<generator object <genexpr> at 0x00000197D78D3190>
Memory Efficiency and Lazy Evaluation of the Generator
• It uses less amount of memory
import sys
• Lazy evaluation
5 seconds passed
import time 0
1
def func(x): 2
time.sleep(1) 3
return x 4
0 1 sec passed
L = [func(x) for x in range(5)] 1 1 sec passed
for item in L: 2 1 sec passed
print(item) 3 1 sec passed
4 1 sec passed
G = (func(x) for x in range(5))
for item in G:
print(item)
Lecture 06
The End