-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIterators_and_iterables.py
More file actions
executable file
·195 lines (137 loc) · 5.51 KB
/
Iterators_and_iterables.py
File metadata and controls
executable file
·195 lines (137 loc) · 5.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
#------------------------------------------------------------------------------------------------------------------#
# Iter, Iterator and Iterables :
#------------------------------------------------------------------------------------------------------------------#
# Iterables : this is something which can be looped over so list is the iterables
'''Specificly
it means that object needs to return an iterator object from its __iter__ method
and iterator that is returend from __iter__ methos must define __next__ method which
accesses elements container one at a times '''
#1. Iterable: An object you can iterate over (e.g., lists, strings).
#2. Iterator: An object that provides a stream of data and has __iter__() and __next__() methods.
#3. iter(): A function to obtain an iterator from an iterable.
''''
iter(): A built-in function to obtain an iterator from an iterable.
__iter__(): A special method in an iterable object that returns an iterator.
next(): A built-in function to get the next item from an iterator.
__next__(): A special method in an iterator that returns the next item.
'''
nums = [1,2,3,4,5,6,7,8,9,10]
print(nums[2])
for num in nums:
print(num)
print(dir(nums))
# if something is iterable than it must have the method called -__iter__()
# so for loop is calling the method __iter__ on the object and retruning the iterator
#Iterator: so iterator is a object in a state and it remeber where it is during iterations
#and they get their next value by the __next__ method
#print(next(nums))
#list doesn't have the __next__ method so it isn't iterator
#-----------------------------------------------------------------------------------#-----------------------------------
# Implement the iter method on the list
#------------------------------------------------------------------------------------------------------------------#
#object is the iterator in a state so it rember where it is during the iterations
it = iter(nums)
print(it.__next__())
print(it.__next__())
print(next(it))
#------------------------------------------------------------------------------------------------------------------#
i_nums = nums.__iter__()
#i_nums= iter(nums)
print(i_nums)
print(dir(i_nums))
print(next(i_nums))
print(next(i_nums))
print(next(i_nums))
print(next(i_nums))
#print(next(i_nums)) #stop iteration error
# so working of the for loop as a iterator follows :
'''
while True:
try:
item = next(i_nums)
print(item)
except StopIteration:
break
'''
#------------------------------------------------------------------------------------------------------------------#
# Creating the Own iter method
#------------------------------------------------------------------------------------------------------------------#
#1.
class Top10:
def __init__(self) -> None:
self.num =1
def __iter__(self):
return self
def __next__(self):
if self.num <=10:
val = self.num
self.num+=1
return val
else:
raise StopIteration
values = Top10()
print(next(values)) # after this only print the from value2
for i in values:
print("Value",i)
#--------------------------------------------------------#--------------------------------------------------------#
# 2. Own Range Function
#--------------------------------------------------------#--------------------------------------------------------#
# It is function for behaving like the built-in class of range function
class MyRange:
def __init__(self,start,end):
self.value = start
self.end = end
def __iter__(self): #making the class iterable
return self
def __next__(self):
if self.value >= self.end:
raise StopIteration
current = self.value
self.value += 1
return current
#Creating generator function iterator :
def myrange(start , end):
current = start
while current < end : # While True:
yield current
current += 1
#------------------------------------------
# use of generator fun and Range Class :
#------------------------------------------
nums = myrange(1,10)
# nums = MyRange(1,10)
#Looping the gen fun or class
for num in nums :
print(num)#------------------------------------------------------------------------------------------------------------------#
#or by next() method
# print(next(nums))
# print(next(nums))
# print(next(nums))
# print(next(nums))
#-----------------------------
# Coding Problem : Creating own Iterators :
#----------------------------
class Sentence:
def __init__(self,sentence):
self.sentence = sentence
self.index = 0 # adding the index attribute
self.words = self.sentence.split()
#making class iterabale
def __iter__(self):
return self
def __next__(self): # for the iterating the object at a iteration state
if self.index >= len(self.words):
raise StopIteration
index = self.index
self.index += 1
return self.words[index] #returns the words index by index
my_sentence = Sentence('This is a test')
for word in my_sentence:
print(word)
# By using the Generator :
def sentence(sentence):
for word in sentence.split():
yield word #it will yield one by like the __next __
my_sentence1 = sentence('This is a test')
for word in my_sentence1:
print(word)