简体   繁体   English

优雅的多入方式?

[英]Elegant way for multiple for in?

What is the elegant way in python for this kind of case ? 在这种情况下,python中的优雅方法是什么?

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

This will work fine: 这将正常工作:

products_names = ', '.join([product.name for movement in movements for product in movement.products])

The list comprehension, creates a list of product.name for all the products. 列表理解,为所有产品创建一个product.name列表。 And then we join the list on ', ' to get the final string. 然后,我们在', 'join列表以获取最终的字符串。

You can also avoid creating the list alltogether, by using a generator expression: 您还可以通过使用生成器表达式来避免一起创建列表:

products_names = ', '.join(product.name for movement in movements for product in movement.products)

Note that, with join() , list comprehension gives better result than generator expression. 注意,使用join() ,列表生成比生成器表达式提供更好的结果。

product_names = ", ".join([product.name for movement in movements for product in movement.products])

This solution takes advantage of the join method of a string as well as a list comprehension . 该解决方案利用了字符串的join方法以及列表理解功能

Note also that I used a comprehension rather than a generator expression. 还请注意,我使用了一种理解而不是生成器表达式。 This is because, while generators are usually faster than comprehensions, the join method actually works better with a comprehension. 这是因为,尽管生成器通常比理解速度快,但是join方法实际上对理解而言更好地工作。 See this reference . 请参阅此参考

Using map and an anonymous function may make it more readable in this case; 在这种情况下,使用map和匿名函数可能使其更具可读性; it's debatable. 这值得商.。

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

reduce could also be used but is probably less readable than the comprehensions: 还可以使用reduce ,但是其可读性可能低于理解:

reduce(lambda y,z: y + ", " + z, map(lambda x: ", ".join(x.products), movements))

You can shorten some of the above examples slightly by using chain , which is great for flattening lists of lists: 您可以通过使用chain略微缩短上面的一些示例,这对于展平列表列表非常有用:

 from itertools import chain

 product_names = ', '.join([x.name for x in chain(*movements)])

Assuming that movements == [l1, l2, l3, ...] and for each l , they look like [p1, p2, p3, p4, ...] , then this is what it does: 假设movements == [l1, l2, l3, ...]并且对于每个l ,它们看起来像[p1, p2, p3, p4, ...] ,那么它的作用是:

 chain(*movements)

This does one level of flattening on movement. 这对运动进行了一个平坦化。 The * rolls out movements into the chain function - ie this is effectively the same as calling chain(l1, l2, l3) . *将动作展开到链函数中-即,这实际上与调用chain(l1, l2, l3)

 [x.name for x in chain(*movements)]

But we actually want some processing on each item, so add a list comprehension to pull the value out we want instead. 但是我们实际上希望对每个项目进行一些处理,因此添加列表推导来代替我们想要的值。

note that the list comprehension is still faster, because of join. 请注意,由于加入,列表理解仍然更快。 without doing lookups, i got the following results: 不进行查找,我得到以下结果:

 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM