这个控制结构是代码味吗?

时间:2009-12-11 05:36:24

标签: python structure controls

这段代码似乎闻到了:

result = None
for item in list:
    if result is None:
        result = item.foo(args)
    else:
        if ClassFred.objects.get(arg1=result) < ClassFred.objects.get(arg1=item.foo(args)):
            result = item.foo(args)

最有气味的部分是“结果”的效用。有人会善意地为我嗤之以鼻吗?

5 个答案:

答案 0 :(得分:3)

L = list # 'list' is a poor variable name, use something else
result = min((n.foo(args) for n in L),
             key=lambda x: ClassFred.objects.get(arg1=x))
# if you don't have to use arg1 as a named parameter:
result = min((n.foo(args) for n in L), key=ClassFred.objects.get)

min函数比较给定项目并返回最小值(当然:P)。一开始并不明显的是,您可以控制用于比较它们的值,这是“关键”参数。

>>> L = [-2, -1, 3]
>>> min(L)
-2
>>> min(L, key=abs)
-1

键函数计算“比较键”,这就是用来比较的。默认键功能是identity,其中项的比较键是项本身。

>>> def identity(x):
...   return x
>>> min(L, key=identity)
-2

另一个例子:

>>> min("0000", "11", "222", "3")
"0000" # lexicographical minimum
>>> min("0000", "11", "222", "3", key=len)
"3"

上面的代码使用item.foo(args)作为值,其中item来自您的列表;但通过ClassFred.objects.get(arg1=..)传递的结果用于比较。这意味着构造是您的关键功能:

values = (n.foo(args) for n in L) # this is a generator expression
# it is similar to a list comprehension, but doesn't compute or store
# everything immediately

def keyfunc(x):
  return ClassFred.objects.get(arg1=x)

result = min(values, key=keyfunc)

我在顶部的代码只是将它们放在一个声明中。

答案 1 :(得分:1)

逻辑太复杂了。很难读懂你在做什么。 简化那个循环,你在那里做得太多了。

这个恕我直言已经是一种非常难闻的气味了。

答案 2 :(得分:1)

倒数第二行是如此之久,我对此失去了耐心。我会用有意义的名字制作这两个独立的变量,所以我们可以弄清楚如果x&lt; y应该是指。

这个怎么样:

if not list:
    return None

def get_thing(bar):
    # I don't know what this is, so... here:
    return ClassFred.objects.get(arg1=bar.foo(args))

# way less hassle than that if-else stuff
biggest = get_thing(list[0])
for item in list:
    current = get_thing(item)
    if biggest < current:
            biggest = current

答案 3 :(得分:1)

所以,我同意它似乎可以从可读性的角度重构,但它应该有效。这是我的看法:

# using lst instead of list & at least python 2.5
result = lst[0].foo(args) if lst else None
fxn = ClassFred.objects.get

for item in lst[1:]:
    if fxn(arg1=result) > fxn(arg1=item.foo(args)):
        result = item.foo(args)

答案 4 :(得分:0)

这可能有用,但我觉得它的味道不会更好:p

max([ClassFred.objects.get(arg1=item.foo(args)), item.foo(args) for item in list])[1]