【问题标题】:Moving first elements before the last element in a list python在列表python中的最后一个元素之前移动第一个元素
【发布时间】:2015-11-14 15:21:43
【问题描述】:

好的,所以我有一个列表,我想将列表开头的元素数移动到列表中最后一个元素之前,其中最后一个元素表示我需要移动的元素数。 例如:[2, 19, 6, 26, 1, 15, 12, 3],因为最后一个元素是 3,所以结果看起来像 [26, 1, 15, 12, 2, 19, 6, 3]。有谁知道我如何以这种方式索引列表?

【问题讨论】:

  • 这是一个挑战吗?是为了一份富有成效的工作吗?请注意,Python 中的列表(与其他语言中的列表不同)并未真正针对移位/滚动操作进行优化。只要您在小列表中有限地使用它,为什么不呢?但是如果你想在一些更繁重的过程中嵌入这样的东西,你应该意识到这些操作的复杂性(参见wiki.python.org/moin/TimeComplexity)并且可能更关注基于索引的系统。通过索引列表的开头而不是真正构建新列表,您可能会保持 O(1) 复杂度而不是 O(n)。

标签: python list slice


【解决方案1】:
  • 要获取列表的最后一项,您可以使用-1th 索引 (l[-1])。

  • 要获取列表的第一个 n 项,请从 0 切片到 n (l[0:n]); Python 会让你省略最初的 0

  • 要获取从n 到列表中倒数第二项的元素,请从n 切片到-1 (l[n:-1])。

把所有这些放在一起,你会使用类似的东西:

def move_items(lst):
    return lst[lst[-1]:-1] + lst[:lst[-1]] + [lst[-1]]

在行动:

>>> def move_items(lst):
...     return lst[lst[-1]:-1] + lst[:lst[-1]] + [lst[-1]]
... 
>>> move_items([2,19,6,26,1,15,12,3])
[26, 1, 15, 12, 2, 19, 6, 3]

【讨论】:

  • 我认为您也可以使用lst[:lst[-1]] 而不是lst[0:lst[-1]]。我通常会看到带有隐式0 的第一种形式。 (现在说“节省 1 个字节”真的很诱人……;)
  • 请注意,如果最后一个数字(表示将移动多少个)是>=,而不是列表中的项目数,它将再次添加它。例如:move_items([2,19,6,26,1,15,12,8]) -> [2, 19, 6, 26, 1, 15, 12, 8, 8].
  • 谢谢门把手!有效。我的方法是使用 bottom_card = deck_cards[-1] 查找底部元素的值,并在所有值中使用 bottom_cards。但我想这也行得通。
【解决方案2】:
def split(x):
  y = x[:]    # make a copy: not to harm incoming list
  numToMove = y.pop()
  return (numToMove, y[:numToMove], y[numToMove:])

a = [2, 19, 6, 26, 1, 15, 12, 3]
(num, head, tail) = split(a)
answer = tail + head + [num]

【讨论】:

    【解决方案3】:

    试试这个:

    l = [2, 19, 6, 26, 1, 15, 12, 3]
    l2 = l[l[-1]:-1] + l[:l[-1]] + [l[-1]]
    print l2
    

    【讨论】:

      【解决方案4】:

      使用模数创建单个列表而不切片的版本:

      def swap(l):
          i, ln = l[-1], len(l) - 1
          for j in range(ln):
              yield l[(i + j) % ln]
          yield i
      

      输出:

      In [2]: l = [2, 19, 6, 26, 1, 15, 12, 3]
      
      In [3]: list(swap(l))
      Out[3]: [26, 1, 15, 12, 2, 19, 6, 3]
      

      或者使用collections.deque

      from collections import deque
      def swap(l):
          ln, deq = len(l) - 1, deque(l)
          i = deq.pop()
          deq.rotate(ln - i), deq.append(i)
          return deq
      

      更精简的版本,但使用更多内存:

      def swap(l):
          i, ln = l[-1], len(l) - 1
          return [l[(i + j)% ln] for j in range(ln)] + [i]
      

      不确定如果最后一个数字 > 列表的长度会发生什么,使用模将意味着循环列表,其中切片会增长您的列表添加重复元素,您可能需要专门处理这种情况。

      【讨论】:

      • 我尝试了你们提出的建议,但无济于事。我需要改变列表。到目前为止,我有 insert_top_to_bottom([1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18, 21, 24, 27, 2, 5, 8 , 11, 14, 17, 20, 23, 26]) [23, 26, 1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 3, 6, 9, 12, 15, 18 , 21, 24, 27, 2, 5, 8, 11, 14, 17, 20]
      • 所以我只需要得到 1,4,7,10,13,16,19,22,25,28,3,6,9,12,15,18,21,24 ,27,2,5,8,11,14,17,20 在 26 前面
      • @vig143,你的意思是改变原始列表?我所有的例子都给了你预期的输出,如果你想改变原始列表,请使用my_list[:] = swap(my_list)
      • 如果您要经常这样做,只需始终使用双端队列,那么您就可以高效轻松地完成所有操作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-21
      • 2016-01-22
      • 2019-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多