Python3制作一个增量一定数量的列表,减少一定数量

时间:2015-02-26 22:47:06

标签: python python-3.x

如果我有以下内容: [0, 1, 2, 3, 4, 5, 6...]如何重新排序列表(实际制作列表的新副本),然后填写:

[0, 1, 2, 3, 4, 5, 10, 9, 8, 7, 6, 11, 12, 13...]

即。每五次迭代,列表开始递减或递增。我想这样做的原因是我有一个对象列表,我想以不同的顺序填充一个包含对象的新列表。

我尝试过的一种技巧是:

copied_icons = [{key:'Object1'}, {key:'Object2'}, {key:'Object3'}...] 
reversed_copied_icons = copied_icons[::-1]
left_to_right = []


for h in range(17):
    left_to_right.append(copied_icons[h])

for j in range(18, 35):
    left_to_right.append(reversed_copied_icons[j])

for k in range(36, 53):
    left_to_right.append(copied_icons[k])

for l in range(54, 71):
    left_to_right.append(reversed_copied_icons[l])

但由于某种原因,这会无序地返回列表并复制一些对象。我想知道在填写我的列表时是否有更简单的方法来交替递增和递减。

2 个答案:

答案 0 :(得分:4)

您的方法存在两个问题:

  1. 您正在撤消整个列表,而不仅仅是那个切片。我们说列表是[1,2,3,4],我们想要反转下半部分,即得[1,2,4,3];根据您的方法,您将从反向列表中[4,3,2,1]获取第三和第四个元素,最后得到[1,2,2,1]
  2. 范围内的to-index是独占的,因此使用range(17)然后使用range(18,35)等等,您错过了索引17上的元素,{{1 }}和35
  3. 您可以使用循环来反转不同的部分,然后以相反的顺序用相同的切片替换列表中的切片。

    53

    或者这样,正如评论中指出的那样,它也摆脱了那些令人讨厌的逐个指数:

    lst = list(range(20))
    for start in range(5, len(lst), 10):
        lst[start:start+5] = lst[start+4:start-1:-1]
    

    之后,for start in range(5, len(lst), 10): lst[start:start+5] = reversed(lst[start:start+5]) lst

    或者,如果要反转的间隔是不规则的(因为它似乎在您的问题中):

    [0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15]

答案 1 :(得分:1)

这似乎可以实现您的目标:

def foo(lst, n=5):
    """ lst=list to be re-ordered, n=item count before reversal """
    new_list = list()
    direction = 1
    start = 0
    end = start
    while start < len(lst):  
        # process through the list in steps of 'n', 
        # except use min for possible stub at end.
        end = start + min(n, len(lst) - start)  # i.e. start+5
        # If direction is 1, append list to new list. Otherwise, append reversed list.
        new_list[start:end] = lst[start:end][::direction]
        direction *= -1  # Switch directions
        start = end  # Jump to new starting position.
    return new_list

lst = np.arange(20).tolist()
foo(lst,5)
[0, 1, 2, 3, 4, 9, 8, 7, 6, 5, 10, 11, 12, 13, 14, 19, 18, 17, 16, 15]

如果方向* = -1行要删除的地方,代码只会复制大小为'n'的块的现有列表(lst),这是你在反转列表之前想要的项目数。

在方向要改变的位置上方,[:: direction]将是[:: 1],在这种情况下,列表将按正常顺序排序,否则[:: - 1],在这种情况下,对于正在处理的大小为n的块,列表将被反转。切片列表时的第三个参数是'步长'参数,因此步长为-1会以相反的顺序返回列表的副本。

如果有一个存根,即你的存根是2,如果你的列表有22个元素,但你的'n'是5步,那么你需要调整你的步长'n',这样你就不会过去列表的末尾。 min(n,len(lst) - start)将确保您不会超过列表的末尾。或者,可能更清楚,你可以使用end = min(start + n,len(lst))。