循环列表的两种方式 - 区别
Posted
技术标签:
【中文标题】循环列表的两种方式 - 区别【英文标题】:two ways of looping over list - difference 【发布时间】:2018-10-22 10:08:24 【问题描述】:我必须反转列表中长度大于 4 的每个单词。所以我尝试了:
for word in words:
if len(word) >= 5:
word = word[::-1]
它没有工作。但是这个:
for i in range(len(words)):
if len(words[i]) >= 5:
words[i] = words[i][::-1]
工作正常。有什么区别?
【问题讨论】:
【参考方案1】:当您遍历列表时,Python 会为您的变量创建引用(具有相同的 ID)。但是,这些是不可编辑的。例如检查这个:Can't modify list elements in a loop Python
考虑这个希望可以帮助你的例子:
words = ['abcdef','abc']
for ind,i in enumerate(words):
print('Loop '.format(ind))
i = i[::-1]
print('words equal '.format(words))
words[ind] = words[ind][::-1]
print('words equal '.format(words))
print()
返回:
Loop 0
words equal ['abcdef', 'abc'] # <--- after changing i (nothing changed)
words equal ['fedcba', 'abc'] # <--- after changing words[ind]
Loop 1
words equal ['fedcba', 'abc'] # <--- after changing i (nothing changed)
words equal ['fedcba', 'cba'] # <--- after changing words[ind]
你的情况
最简单的解决方案是使用列表推导。考虑一下:
rWords = [word[::-1] if len(word) >=5 else word for word in words]
【讨论】:
【参考方案2】: word = word[::-1]
word 没有引用到 words[i]。 您可以通过函数式编程来做到这一点。
new_words = list(word[::-1] if len(word) >= 5 else word for word in words)
【讨论】:
【参考方案3】:要了解这里发生了什么,请比较一个类似示例中发生的情况,我想将任何大于 20 的数字设置为 -1:
numbers = [1, 10, 30, 40, 50]
for number in numbers:
if number > 20:
number = -1
print(numbers) # same as before!
为什么不将最后三个数字设置为 -1?因为number
这里是一个值——它在内存中的位置与numbers
数组的内容完全无关。您的示例中的word
完全相同。
在您的循环中,word
绑定到一块新内存,其内容恰好与words
数组的当前条目相同。在您的第一个 sn-p 中定义 word
时,您已经失去了任何方法来操作它来自的数组位置。通过像在第二个 sn-p 中那样遍历索引,您可以在数组中保留一个后门。
这两个参考,
http://foobarnbaz.com/2012/07/08/understanding-python-variables/ 和 https://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/可能有助于理解以下棘手的问题:如果我们有一个列表列表而不是字符串列表,会发生什么?
listOfLists = [[1], [2, 3], [9, 10, 11], [40, 50, 60, 70]]
for l in listOfLists:
if len(l) >= 3:
l[:] = l[::-1] # note that `[:]`!!!
print(listOfLists)
这实际上将反转具有超过 2 个元素的任何子列表。你能明白为什么吗?如果是这样,请收下这颗金星:?!
【讨论】:
【参考方案4】:原因是当你做第一个时,你只是修改了word
变量,你没有修改words
列表。但是当您使用第二个示例时,您正在修改它,因为您使用的是words[i] = words[i][::-1]
。在此示例中,您正在修改单词列表,因为 words[i]
是修饰符;您正在将列表的元素设置为某些内容。
【讨论】:
以上是关于循环列表的两种方式 - 区别的主要内容,如果未能解决你的问题,请参考以下文章