0

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

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

4 回答 4

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(),列表推导比生成器表达式提供更好的结果。

于 2013-10-11T14:16:19.797 回答
3

在这种情况下,使用map和 匿名函数可能会使它更具可读性;这是有争议的。

", ".join(map(lambda x: ", ".join(x.products), movements))

reduce也可以使用,但可能比理解更易读:

reduce(lambda y,z: y + ", " + z, map(lambda x: ", ".join(x.products), movements))
于 2013-10-11T14:21:19.130 回答
3
product_names = ", ".join([product.name for movement in movements for product in movement.products])

该解决方案利用join了字符串的方法以及列表推导

另请注意,我使用了理解而不是生成器表达式。这是因为,虽然生成器通常比推导式更快,但该join方法实际上更适合推导式。请参阅此参考

于 2013-10-11T14:17:05.357 回答
1

您可以使用 稍微缩短上面的一些示例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
于 2013-10-11T14:52:19.833 回答