优雅的方式为多个in?

时间:2013-10-11 14:14:57

标签: python

对于这种情况,python的优雅方式是什么?

products_names = ''
for movement in movements:
  for product in movement.products:
    products_names += product.name + ', '

4 个答案:

答案 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