Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:列表项在for循环中没有更改_Python_List_Loops - Fatal编程技术网

Python:列表项在for循环中没有更改

Python:列表项在for循环中没有更改,python,list,loops,Python,List,Loops,当以下代码没有达到我预期的效果时,我感到震惊: lines_list = ['this is line 1\n', 'this is line 2\n', 'this is line 3\n'] for line in lines_list: line = line.strip() 我当然希望列表中的每一项都变成“stripped”,即在本例中,没有尾随的'\n'字符,但它没有 print lines_list 输出: ['this is line 1\n', 'this is li

当以下代码没有达到我预期的效果时,我感到震惊:

lines_list = ['this is line 1\n', 'this is line 2\n', 'this is line 3\n']
for line in lines_list:
    line = line.strip()
我当然希望列表中的每一项都变成
“stripped”
,即在本例中,没有尾随的
'\n'
字符,但它没有

print lines_list
输出:

['this is line 1\n', 'this is line 2\n', 'this is line 3\n']
正如您所猜测的,我的问题是,在
for
循环期间,是否有一种优雅的方法来更改列表项?我不想重复这个列表

编辑

顺便提一下,在PerlJava中,我的使用效果很好。Python是具有独特行为的

在Java中,这将起作用:

String[] lines = {"this is line 1\n", "this is line 2\n", "this is line 3\n"};
for (String line : lines) {
    line = line.trim();
}
my @lines = ("this is line 1\n", "this is line 2\n", "this is line 3\n");
foreach my $line (@lines) {
    $line =~ s/\s+$//;
    $line =~ s/^\s+//;
}
在Perl中,这将起作用:

String[] lines = {"this is line 1\n", "this is line 2\n", "this is line 3\n"};
for (String line : lines) {
    line = line.trim();
}
my @lines = ("this is line 1\n", "this is line 2\n", "this is line 3\n");
foreach my $line (@lines) {
    $line =~ s/\s+$//;
    $line =~ s/^\s+//;
}

您可以通过索引进行检查,并以这种方式就地修改

for i, _ in enumerate(lines_list):
    lines_list[i] = lines_list[i].strip()
虽然我认为很多人更喜欢简单的复制列表,如果列表不是那么大,它会导致一个问题

lines_list = [line.strip() for line in lines_list]
问题是使用
=
运算符重新分配变量
,它不会影响原始字符串的内容。在以下情况下,新的python程序员同样经常感到惊讶:

for i in range(10):
    print(i)
    i += 1
打印数字0,1,2,3,4,5,6,7,8,9。这是因为for循环在每次迭代开始时将
i
重新分配给范围中的下一个元素。这不完全是你的问题,但也很相似

因为您正在从文件中读取行,然后将它们剥离,所以您真正应该做的是

with open(file_name) as f:
    lines_list = [line.strip() for line in f]

在您的示例中,
line
只是一个变量。它未连接到可能来自的列表。想一想,如果每个变量都修改它的原点,会出现什么问题

在python中,通常不会修改列表,但会创建一个新列表。因此有一种叫做列表理解的东西:

lines_list = [line.strip() for line in lines_list]

您确实忘了为某些内容指定新值(剥离字符串)

另一种方法是,如何以较短的方式将其分配给列表:

>>> lst = ['this is line 1\n', 'this is line 2\n', 'this is line 3\n']
>>> import string
>>> lst = map(string.strip, lst)
>>> lst
['this is line 1', 'this is line 2', 'this is line 3]

我同意,但我觉得它不那么优雅。另外,我猜(但没有证据)使用索引而不是迭代器访问列表项在性能上更昂贵。在我看来,您添加的新解决方案更漂亮。谢谢@用户3322273好奇的是,你是通过将文件读入列表来获得这些行的吗?Ryan的回答很酷。通常(取决于内存限制),在迭代时更改正在迭代的集合(事实上,某些语言,如C#,禁止并将通过编译时错误)不是一种好的做法,因为这会带来(有时)可以避免的复杂性(每次迭代都使用修改过的集合)。是的,但我不想让人们注意文件阅读,所以我在这里展示了一个硬编码列表。但是五年后还是一样的,但是java示例也没有修改原始的
,因为同样的原因,python示例五年后也没有修改,这对我来说真的很奇怪。由于字符串是不可变的,我不希望
line=line.trim()
影响数组中的引用。这是相同的原因,因为您正在将
line
更改为引用新字符串。即使使用可变类型,
=
也不会更改左侧的对象,
[]=
则不同。