对于这种情况,python 中的优雅方式是什么?
products_names = ''
for movement in movements:
for product in movement.products:
products_names += product.name + ', '
对于这种情况,python 中的优雅方式是什么?
products_names = ''
for movement in movements:
for product in movement.products:
products_names += product.name + ', '
这将正常工作:
products_names = ', '.join([product.name for movement in movements for product in movement.products])
列表理解,product.name
为所有产品创建一个列表。然后我们join
在列表上', '
得到最终的字符串。
您还可以通过使用生成器表达式来避免一起创建列表:
products_names = ', '.join(product.name for movement in movements for product in movement.products)
请注意,使用join()
,列表推导比生成器表达式提供更好的结果。
在这种情况下,使用map
和 匿名函数可能会使它更具可读性;这是有争议的。
", ".join(map(lambda x: ", ".join(x.products), movements))
reduce
也可以使用,但可能比理解更易读:
reduce(lambda y,z: y + ", " + z, map(lambda x: ", ".join(x.products), movements))
您可以使用 稍微缩短上面的一些示例chain
,这对于扁平化列表非常有用:
from itertools import chain
product_names = ', '.join([x.name for x in chain(*movements)])
假设movements
==[l1, l2, l3, ...]
并且对于 each l
,它们看起来像[p1, p2, p3, p4, ...]
,那么这就是它的作用:
chain(*movements)
这对运动进行了一层扁平化。* 将动作展开到链函数中——即这实际上与调用相同chain(l1, l2, l3)
。
[x.name for x in chain(*movements)]
但是我们实际上想要对每个项目进行一些处理,所以添加一个列表推导来提取我们想要的值。
请注意,由于加入,列表理解仍然更快。不做查找,我得到以下结果:
tl = [['a', 'b', 'c'], ['c', 'd', 'e'], ['e', 'f', 'g']]
%timeit ','.join(chain(*tl))
100000 loops, best of 3: 1.78 us per loop
%timeit ','.join([x for l in tl for x in l])
1000000 loops, best of 3: 1.09 us per loop
%timeit ','.join([x for x in chain(*tl)])
1000000 loops, best of 3: 1.41 us per loop