降低以下代码的复杂性

时间:2010-12-12 12:01:25

标签: python

我想要做的是搜索列表并删除值。

所以我写了下面的代码

for x in range(10):
   if x in list1:
      list1.remove(x)

这个函数是否为〜(n ^ 2),因为它首先查找该值,然后删除并向后推其余的值?

还有一种方法可以通过使用try / except

按顺序n来转换它
try:
  for x in range(10):
    list1.remove(x)
except ValueError:
  # make it go back to next iteration 

6 个答案:

答案 0 :(得分:5)

使用:

L = [x for x in L if x not in removal_list]

removal_list可以是任何容器,但如果你使用set()或frozenset(),你将获得O(n)(n = len(L))。

答案 1 :(得分:2)

这听起来像是filter()的工作:

>>> filter(lambda x: not x in (4, 5, 7), xrange(10))
[0, 1, 2, 3, 6, 8, 9]

更新:我使用list comprehension构建列表的另一个示例:

>>> filter(lambda x: not x[0] in (4, 5, 7), [[a] for a in xrange(10)])
[[0], [1], [2], [3], [6], [8], [9]]

答案 2 :(得分:1)

更换切片:

a[:] = ( l for l in a if l not in set(list_of_removable))

答案 3 :(得分:0)

蟒蛇不是我的地区,但有些事情会浮现在脑海中。首先,列表有多大,因为你要多次迭代它。如果它很大,那么翻转它可能是一个更好的主意,所以你只需要迭代它一次。

其次,如果Python就像Java,那么就有一个好的代码规则 - 不要为流程流使用异常。这排除了你的第二个建议。它也可能表现不佳。

答案 4 :(得分:0)

就像Giovanni Bajo所说,列表理解很酷,但假设你只使用一次结果,那么生成器就更好了:

l = [1,23,2,24,3,26,1]
(x for x in l if x not in xrange(10))

xrange()也是一个生成器,速度比range()快 如果你想多次使用结果我会去:

[x for x in l if x not in xrange(10)]

答案 5 :(得分:0)

回答最初的问题:没有必要将list-to-remove-elements-from的每个元素与list-containing-removable-elements的每个元素进行比较。所以在这个意义上,这个代码的每个版本都是O(N ^ 2)(假设我们每个列表中可以有任意多个元素)。你可以通过使用各种结构隐藏循环(在很多情况下它会更快,因为循环可以在解释器的C代码中“内部”完成,而不是通过解释更多的字节码),但循环仍然是那里(并记住大O分析忽略了常数因素)。