对于这种情况,python的优雅方式是什么?
products_names = ''
for movement in movements:
for product in movement.products:
products_names += product.name + ', '
答案 0 :(得分:6)
这样可以正常工作:
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()
,list comprehension比生成器表达式提供更好的结果。
答案 1 :(得分:3)
product_names = ", ".join([product.name for movement in movements for product in movement.products])
此解决方案利用字符串的join
方法以及list comprehension。
另请注意,我使用的是理解而不是生成器表达式。这是因为,虽然生成器通常比理解更快,但join
方法实际上更适合理解。请参阅此reference。
答案 2 :(得分:3)
在这种情况下,使用map
和匿名函数可以使其更具可读性;这是值得商榷的。
", ".join(map(lambda x: ", ".join(x.products), movements))
reduce
也可以使用,但可能性低于理解力:
reduce(lambda y,z: y + ", " + z, map(lambda x: ", ".join(x.products), movements))
答案 3 :(得分:1)
您可以使用chain
稍微缩短上述一些示例,这对于展平列表列表非常有用:
from itertools import chain
product_names = ', '.join([x.name for x in chain(*movements)])
假设movements
== [l1, l2, l3, ...]
和每个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