【问题标题】: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]

工作正常。有什么区别?

【问题讨论】:

    标签: python list


    【解决方案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 中那样遍历索引,您可以在数组中保留一个后门。

        这两个参考,

        可能有助于理解以下棘手的问题:如果我们有一个列表列表而不是字符串列表,会发生什么?

        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] 是修饰符;您正在将列表的元素设置为某些内容。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-19
            相关资源
            最近更新 更多