2015-07-11 207 views
2

对于一个赋值,我必须在不使用Python中的内置函数的情况下过滤列表。这里是我的代码:在Python中过滤字符串列表

def satisfiesF(L): 
    result = 0 
    i = 0 
    L1 = [] 
    while i < len(L): 
     s = L[i] 
     if f(s) == True : 
      result += 1 
      L1.append(L[i]) 
     i += 1 
    L = L1 
    print L 
    return result 
def f(s): 
    return 'a' in s 
L = ['a', 'b', 'a'] 
print satisfiesF(L) 
print L 

它打印:

['a', 'a'] 
2 
['a', 'b', 'a'] 

为什么第二L不一样,第一个?我已经搜索了几个小时,但我不明白。在我看来,这里L是通过引用传递的,所以为什么价值没有变化?

我试过改变线L = L1L = list(L1)但结果是一样的。

回答

0
L = L1 

这使得L参考列表L1引用。在此行前后添加print(id(L)),您可以看到其id已更改。保持

一种方式L相同id同时获得的L1的内容是先清除它,然后附加:

del L[:] 
L.append(L1) 
0

这是局部和全局变量范围的一个简单错误。

里面的功能satisfiesF(L)

L = L1 

,这种变化是,你传递给函数satisfiesF()为参数的函数内声明的L。你可能已经通过L'并试图打印L',它会工作得很好。但是print L会给出variable out of scope错误。

但是,当你在最后一行做

print L 

,将打印在它上面的L声明只是两行L = ['a', 'b', 'a']

+0

我明白,但我怎么避免呢?我如何更改L?我刚刚发现,“Python语言中的所有参数(参数)都是通过引用传递的,这意味着如果你改变了一个函数中引用的参数,那么这个改变也反映回调用函数”(http:// www。 tutorialspoint.com/python/python_functions.htm) –

+0

你可以通过在顶层声明它(你已经完成)并将一个不同的名称传递给你的函数来改变L,比如'L''并且从里面改变L的值该功能将完成这项工作。 –

+0

或者你根本不需要传递任何参数,因为它是全局声明的。 –

0

由于人士Himanshu指出,范围是问题。这就是为什么这个作品,因为它集self.L

class my_test: 
    def __init__(self, values, check): 
     self.L = values 
     self.check = check 

    def run_test(self): 
     print self.satisfiesF() 
     print self.L 

    def f(self, s): 
     return self.check in s 

    def satisfiesF(self): 
     result = 0 
     i = 0 
     L1 = [] 
     while i < len(self.L): 
      s = self.L[i] 
      if self.f(s) == True : 
       result += 1 
       L1.append(self.L[i]) 
      i += 1 
     self.L = L1 
     print self.L 
     return result 

x = my_test(['a', 'b', 'a'], 'a') 
x.run_test() 

输出是

['a', 'a'] 
2 
['a', 'a'] 
+0

我明白你做了什么,但它不能帮助我,因为就像我说过的,我必须将其作为一项任务的一部分来完成,而且我只能修改satisfiesF而不是其余部分,并且当我尝试代码时,出现错误说:'list'对象没有属性'L' –

+0

在Q中它听起来像你写的函数,并没有修改/修复现有的函数。不知道为什么你有错误,我没有。你总是可以返回'L'而不是'result',或者返回'[L,result]'然后把它整理出来 –