1.什么是可迭代对象?
可迭代对象在我看来就是一种可以遍历的对象比如列表,字典,元组,字符串等等。举个例子:
list1 = [1, 2, 3, 4, 5]
for i in range(len(list1)):
print(list1[i])
for i in range(len("hello,world")):
print("hello,world"[i])
tuple1 = (1, 2, 3, 4, 5)
for i in range(len(tuple1)):
print(tuple1[i])
dict1= {"apple": 20, "banana":30}
for k, v in dict1.items():
print("k", k)
print("v", v)
以上都是可迭代对象。
2.yield关键字
迭代用于处理大量数据时候存在一些问题。1.比如列表中的元素太多了会导致大量占用内存。2.有些数据可能只使用一次,如果用列表保存起来有点浪费。所以在这种情况下,我们可以使用生成器。生成器可以有效创建迭代器,像常规函数一样撰写,在返回数据时使用yield语句。
for i in range(len("hello,world")):
print("hello,world"[i])
print("---------------------------------")
str1 = "hello,world"
def print_helloworld(s1):
for idx in range(len(s1)):
yield s1[idx]
generator1 = print_helloworld(str1)
for i in generator1:
print(i)
print(type(generator1))
输出都是一样的:
h
e
l
l
o
,
w
o
r
l
d
---------------------------------
h
e
l
l
o
,
w
o
r
l
d
<class 'generator'>
上面代码定义了一个生成器函数,当代码执行到yield的时候会返回yield之后的语句,感觉和return有点像但是不一样。return返回会释放内部定义的变量,但是生成器会保持退出时候的状态。如果上面yield换成return就只会返回s1[0],但是生成器会一直调用直到不满足条件。最后使用type查看类型发现正好是生成器(generator)
自己调代码遇到的yield的实际使用
class AspectRatioGroupedDataset(data.IterableDataset):
"""
将具有相似纵横比的批量数据组合在一起。在此实现中,长宽比<(或>)1的图像将一起分批进行。
这提高了训练速度,因为图像需要更少的填充形成一批。
它假设底层数据集生成带有“宽度”和“高度”键的字典。
然后它将生成一个长度=batch_size的原始字典列表,全部具有相似的长宽比。
"""
def __init__(self, dataset, batch_size):
"""
Args:
dataset: an iterable. Each element must be a dict with keys
"width" and "height", which will be used to batch data.
batch_size (int):
"""
self.dataset = dataset
self.batch_size = batch_size
self._buckets = [[] for _ in range(2)]
# Hard-coded two aspect ratio groups: w > h and w < h.
# Can add support for more aspect ratio groups, but doesn't seem useful
def __iter__(self):
for d in self.dataset:
w, h = d["width"], d["height"]
bucket_id = 0 if w > h else 1
bucket = self._buckets[bucket_id]
bucket.append(d)
if len(bucket) == self.batch_size:
data = bucket[:]
# Clear bucket first, because code after yield is not
# guaranteed to execute
del bucket[:]
yield data