一、开篇
在学习pytorch的时候,突然看到这样一串代码:
' '.join('%5s' % (i*3) for i in 'Love')
然而我的疑惑是:后面这一串'%5s' % (i*3) for i in 'Love From Heart'代表什么意思呢?join函数传入的参数可以是列表、元组、字符串,这里传入的是推导式呀,怎么理解呢?
后来我发现,很难理解,因为很少人讲过如何把推导式引入函数参数,推导式能作为函数参数吗?
强行理解吧!不妨就把推导式作为函数参数的一种,上面的这一串代码等同于。
' '.join(('%5s' % (i*3) for i in 'Love'))
也就是说用推导式作为函数时可以不用中括号、圆括号括起来,直接可以传入。
上面这一串代码的输出是:
' LLL ooo vvv eee'
二、进化篇
最近在学yolo的源码,在common.py文件中看到了以下代码块。
class BottleneckCSP(nn.Module):
# CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5): # ch_in, ch_out, number, shortcut, groups, expansion
super().__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)
self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)
self.cv4 = Conv(2 * c_, c2, 1, 1)
self.bn = nn.BatchNorm2d(2 * c_) # applied to cat(cv2, cv3)
self.act = nn.SiLU()
self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))
最后一行, 可以看到它先用了一个列表推导式,然后用一个圆括号变成元组,最后在元组前加*操作符解包,使元组中单独的元素成为nn.Sequential函数的传入参数。
我感觉ultalytics的意思应该是,这样先用圆括号装包,然后用*解包,更加安全、稳定、兼容一些?