将循环更改为Python列表理解

时间:2013-07-24 16:05:31

标签: python loops list-comprehension

有一个对象列表,“游戏”。如何检查对象是否具有属性集,如果没有,请使用列表推导设置属性....

for g in games:
        if not g.score_ratio_h1: g.score_ratio_h1 = avg_score_ratio_h1

2 个答案:

答案 0 :(得分:4)

这是使用列表推导的一个好例子,实际上是:it's very anti-Pythonic。循环不会导致创建新的值列表,它只是一系列赋值。最好坚持使用循环,它很好。只有你的代码看起来像这样:

ans = []
for g in games:
    if not g.score_ratio_h1:
        ans.append(g.score_ratio_h1) # we're appending the results

...然后使用理解是个好主意。但目前循环的核心是一项任务:

g.score_ratio_h1 = avg_score_ratio_h1

没有有用的值返回,它是一个不会在任何地方收集的修改操作(“副作用”)。在这种情况下,并不打算使用理解。更重要的是:尝试在理解中进行分配将导致错误,例如:

lst = [[0], [0], [0]]
[a[0] = 1 for a in lst]
      ^
SyntaxError: invalid syntax

答案 1 :(得分:0)

你可以做一些使用列表理解的东西:

for g in (g for g in games if not g.score_ratio_h1):
    g.score_ratio_h1 = avg_score_ratio_h1

它可能有点快......但很奇怪:))

编辑:

我同意这两条评论,但根据“if”条件,这可能并不完全是浪费,这里有一个例子:

  lst = [0 for _ in xrange(708)]
  for i in xrange(100000000):
      if i**2 < 500000:
          lst[i] += i

时间:

real    0m12.906s
user    0m12.876s
sys     0m0.008s

lst = [0 for _ in xrange(708)]
for i in (i for i in xrange(100000000) if i**2 < 500000):
    lst[i] += i

时间:

real    0m8.857s
user    0m8.792s
sys 0m0.016s

我想这取决于条件和循环的大小,这可能确实很浪费,但有时它可能有助于解决列表理解,即使在这种情况下。