【问题标题】:Cycling values of a list [duplicate]列表的循环值[重复]
【发布时间】:2019-03-11 11:47:38
【问题描述】:

我是编码新手,正在尝试编写一个简单的代码,该代码将采用一个列表,例如 [1,2,3] 并将元素循环 n 次。所以如果 n=1,我应该得到 A=[3,1,2]。如果n=2,我应该得到A=[2,3,1]。我写的代码是:

n=1
j=0
A = [1,2,3]
B = [None]*len(A)

while j<=n:
     for i in range(0,len(A)):
         B[i] = A[-1+i]
     j=j+1
print(B)

问题是,无论 n 的值是多少,我都会得到相同的答案,只循环一次。我认为问题在于循环每次都在同一个 B 中循环,所以我需要将新 B 存储为其他内容,然后用新 B 重复循环。但我不知道该怎么做。任何提示将不胜感激

【问题讨论】:

    标签: python python-3.x list for-loop


    【解决方案1】:

    请参阅@sacul's answer 了解您的代码问题。但是list 并不是最适合这种要求的结构,因为每个班次都有 O(n) 复杂度。

    collections 模块中的deque(“双端队列”)通过其rotate 方法提供此功能。此方法就地工作并且具有 O(k) 复杂度,其中 k 是表示旋转次数的参数。这是一个例子:

    from collections import deque
    
    d = deque([1,2,3])
    d.rotate(2)
    
    print(d)
    
    deque([2, 3, 1])
    

    【讨论】:

      【解决方案2】:

      基于itertools 的解决方案

      from itertools import cycle, islice
      
      def roll(x, n):
          start = len(x) - n
          return islice(cycle(x), start, start + len(x))
      

      如果我们循环遍历 x 中的值(实际上我们最多只会这样做两次)。然后对其进行切片,使其从我们想要的元素开始并包含正确数量的元素。

      它可能比其他一些解决方案更深奥一点,但值得一提,因为有很多选择。

      itertools.islice 返回一个生成器。如果您想打印结果,您需要将其转换为list

      【讨论】:

        【解决方案3】:

        一个更简单的函数是:

        def roll(L, n):
            n %= len(L)
            return L[-n:] + L[:-n]
        
        A = [1,2,3]
        roll(A, 1)   # [3, 1, 2]
        roll(A, 2)   # [2, 3, 1]
        roll(A, 3)   # [1, 2, 3]
        roll(A, 4)   # [3, 1, 2]
        

        取模数 (n %= len(L)) 避免了循环遍历的需要。然后,我们只需将列表末尾的一个适当大小的切片连接到它的开头。

        【讨论】:

          【解决方案4】:

          @sacul 的回答有效,但你已经接近了!在创建新的 B 后,您错过了更新 A 以进行 while 循环的下一次迭代。

          n=1
          j=0
          A = [1,2,3]
          B = [None]*len(A)
          
          while j<=n:
              for i in range(0,len(A)):
                  B[i] = A[-1+i]
              A = B[:] # update A so that next time B works on the new A 
              print('A is now ', A) # to debug
              j=j+1
          
          print(B)
          

          这会产生以下打印语句:

          A is now  [3, 1, 2]                                                                                                                   
          A is now  [2, 3, 1]                                                                                                                   
          [2, 3, 1] # this is what finally B is
          

          【讨论】:

          • 但是对于 n = 1,这是错误的结果...改为设置 while j&lt;n
          • @Stuart “错误”是什么意思? j = 1 可以表示 2 次迭代;这只是定义问题。这是 OP 的原始代码,只是稍作修改以解释哪里出错了。
          • 错误,因为它没有为给定的An 提供 OP 指定的输出。
          • 好的,我现在知道如何像我最初所说的那样更新 B。我曾试图说 B=A,但我看看如果我交换顺序,我会得到我的问题之一
          【解决方案5】:

          由于有人已经回答了您的问题,因此不再深入。但是这里需要注意的一个重要属性也是

          A = [1, 2, 3] #Assuming that the length of the matrix you want to rotate is of length 3
          
          If you want to cycle/rotate by 3, then you want to actually cycle/rotate by `len(A)%3` = 0
          If you want to cycle/rotate by 6, then you want to actually cycle/rotate by `len(A)%6` = 0
          If you want to cycle/rotate by 4, then you want to actually cycle/rotate by `len(A)%3` = 1
          If you want to cycle/rotate by a number lesser than the length itself.. then just rotate it by that number!
          
          so if you want to cycle by 2, then well.. rotate it by two.. 
          

          【讨论】:

            【解决方案6】:

            我认为你过于复杂了。考虑将其更改为以下内容:

            n = 1
            A = [1,2,3]
            B = A.copy()
            
            for _ in range(n):
                # Cycle through by concatenating the last element and all other elements together 
                B = [B[-1]]+B[0:-1]
            
            print(B)
            

            如果是n=1,你得到[3, 1, 2]n=2 给你[2, 3, 1]

            请注意,您正在尝试做的事情是在numpy.roll 中实现的(我想您是在询问过程,而不是结果,但以防万一)

            import numpy as np
            
            >>> np.roll(A,1)
            array([3, 1, 2])
            >>> np.roll(A,2)
            array([2, 3, 1])
            

            【讨论】:

            • 两个列表索引之间的关系是j = (j-n)%k,其中j 是循环列表索引,k 是列表长度。使用数组这将非常有效。直接索引列表仍然是可以接受的(在 python 思维中)。然而,让我感到困惑的是,对于这样一个常见的问题,必须在所有地方创建、加入和销毁列表。
            • 您可以进一步将B[0:-1]简化为B[:-1]
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2018-10-29
            • 2021-01-14
            • 2018-11-24
            • 1970-01-01
            • 1970-01-01
            • 2018-05-27
            • 2013-07-06
            相关资源
            最近更新 更多