在python中使用列表时遇到问题

在python中使用列表时遇到问题,python,list,python-2.7,Python,List,Python 2.7,函数satisfiesF()将字符串列表L作为参数。函数f以字符串作为参数,返回true或false。函数satisfiesF()修改L,使其仅包含那些字符串,其中f(s)返回true。 我有两个不同的计划,旨在产生相同的输出。但是我得到了不同的结果 第一个方案: def f(s): return 'a' in s def satisfiesF(L): k=[] for i in L: if f(i)==True: k.appen

函数satisfiesF()将字符串列表L作为参数。函数f以字符串作为参数,返回true或false。函数satisfiesF()修改L,使其仅包含那些字符串,其中f(s)返回true。 我有两个不同的计划,旨在产生相同的输出。但是我得到了不同的结果

第一个方案:

def f(s):
    return 'a' in s

def satisfiesF(L):
    k=[]
    for i in L:
        if f(i)==True:
            k.append(i)
    L=k
    print L
    print
    return len(L)


L = ['a', 'b', 'a']
print satisfiesF(L)
print L
输出:

['a','a']

二,

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

第二个方案:

def f(s):
    return 'a' in s


def satisfiesF(L):
    for i in L:
        if f(i)==False:
            L.remove(i)

    print L
    print
    return len(L)

L = ['a', 'b', 'a']
print satisfiesF(L)
print L
输出:

['a','a']

二,

['a','a']


请解释为什么它们给出不同的输出。

在第一个函数中,您在
satisfiesF()
中分配了
L
,但您从未修改原始列表。当您编写
L=k
时,这使得引用
L
现在引用与
k
相同的列表。它不会分配给原始列表

相反,在第二个函数中,修改
L
,而不重新分配给它

另外,作为补充说明,您不应该在迭代列表时修改它

另一方面,您可以将
满意度f
重写为一行:

L = [item for item in L if f(item)]

在第一个函数中,您在
satisfiesF()
中分配了
L
,但从未修改原始列表。当您编写
L=k
时,这使得引用
L
现在引用与
k
相同的列表。它不会分配给原始列表

相反,在第二个函数中,修改
L
,而不重新分配给它

另外,作为补充说明,您不应该在迭代列表时修改它

另一方面,您可以将
满意度f
重写为一行:

L = [item for item in L if f(item)]
这被错误地否决了。问题变了。因此,答案过时了。以下是更改后的问题的答案: 这意味着我们失去了对L的引用

那么,试试这个:
对于第一个计划,对上述作业进行注释,执行以下操作,以保留对L的引用:

# L=k
del L[:]
L[:] = k
现在两个程序的输出相同,如下所示:

['a', 'a']

2
['a', 'a']
祝你好运。

这一点被错误地否决了。问题变了。因此,答案过时了。以下是更改后的问题的答案: 这意味着我们失去了对L的引用

那么,试试这个:
对于第一个计划,对上述作业进行注释,执行以下操作,以保留对L的引用:

# L=k
del L[:]
L[:] = k
现在两个程序的输出相同,如下所示:

['a', 'a']

2
['a', 'a']

祝您好运。

在第二个函数中,您将
2
视为函数外部的长度和
L
中的所有元素,因为您正在设置一个局部变量
L
,它是对
k
的引用,因此在函数外部创建的
L
不会受到影响。要查看
L
中的更改,您需要使用
L[:]=k
,然后当您更改传递给函数的原始列表对象
L
列表时,打印
L
将在函数外部提供
['a','a']

在第一个示例中,您直接修改
L
,因此您可以看到函数外部的
L
中的更改

此外,如果您要删除列表中的元素,请不要迭代该列表
L=['a','b','a','a','d','e','a']
,你会得到意想不到的行为。在第二个函数中,您将
2
视为长度,并且
L
中的所有元素都位于函数外部,因为您正在设置一个局部变量
L
,它是对
k
的引用,在函数外部创建的
L
不受影响。要查看
L
中的更改,您需要使用
L[:]=k
,然后当您更改传递给函数的原始列表对象
L
列表时,打印
L
将在函数外部提供
['a','a']

在第一个示例中,您直接修改
L
,因此您可以看到函数外部的
L
中的更改

此外,如果您要删除列表中的元素,请不要迭代该列表
L=['a','b','a','a','d','e','a']
,你会得到意想不到的行为。为L[:]中的i复制一份
或为反向(L)中的i使用反向

在问题中,有两个L。一个是全球的,一个是本地的。这个
打印L
语句打印全局L,您在程序中没有对其进行变异

因此,为了让程序知道您想要变异全局L,而不是局部L,您可以添加行
globals()['L']=L

你的第一个节目。我希望这能有所帮助

问题中有两个L。一个是全球的,一个是本地的。这个
打印L
语句打印全局L,您在程序中没有对其进行变异

因此,为了让程序知道您想要变异全局L,而不是局部L,您可以添加行
globals()['L']=L

你的第一个节目。我希望这能有所帮助

在第一个程序中,如果您想改变原始列表L并查看函数所做的更改,则应将代码中的
L=K
替换为
L[:]=K

def satisfiesF(L):
    k=[]
    for i in L:
        if f(i)==True:
            k.append(i)

    # new code --------
    L[:] = k   # before: L = K
    # -----------------

    print L
    print
    return len(L)
这将给你函数外的['a','a']

关于在第二个程序中对循环中的列表进行变异… 请记住,在“for”循环期间,python使用在每次迭代结束时递增的内部计数器跟踪它在列表中的位置

当计数器的值达到列表的当前长度时,循环终止。这意味着,如果在循环中改变列表,可能会产生令人惊讶的结果

例如,查看下面的For循环:

my_list = ['a', 'b', 'c', 'd']

>>>print "my_list - before loop: ", my_list
my_list - before loop:  ['a', 'b', 'c', 'd']


for char in my_list:
    if char == 'a' or char == 'b':
        my_list.remove(char)

>>>print "my_list - after loop: ", my_list    
my_list - after loop:  ['b', 'c', 'd']
这里,隐藏计数器从索引0开始,发现“a”(在我的_列表[0]中)i