【问题标题】:Copying lists in python在python中复制列表
【发布时间】:2013-07-04 12:12:39
【问题描述】:

我对 Python 比较陌生。 我正在尝试提出一个函数,该函数接受一个列表,在该列表中随机添加 +1 到一个值,然后将一个带有修改后的值的新列表作为新索引放置。

例如,如果我有

blank=[]
list_one=[1,2,3,4,5] # 

可能的结果可能是

blank=[ [1,2,3,4,5], [1,3,3,4,5],[1,3,3,4,6],[2,3,3,4,6],[2,4,3,4,6] ]

所以该函数获取空白[0],复制并修改它,并将其作为空白[1]返回。类似地,该函数获取空白[1],复制并修改它,并将其返回为空白[2]

这是我的代码:

import random
list_one=[1,2,3,4,5]
def new_function(value):
    for i in range(1,value):
        list_copy=list_one[:]
        blank.append(list_copy)
        x=random.choice(blank[i])
        y=blank[i].index(x)
        blank[i][y]=x+1
    return blank

print new_function(4) 
"""Yields [ [1,2,3,4,5],[1,3,3,4,5],[2,2,3,4,5],[1,2,4,4,5] ] 
   (this is the list, blank)"""

我的问题是空白[1]、空白[2]和空白[3]都是空白[0]的修改,当每个索引列表应该是前一个索引列表的修改时。

我在这里做错了什么???

【问题讨论】:

  • 请注意,我一直发现使用list(seq) 复制列表比seq[:] 更易于阅读。后者对新用户来说可能有点神秘,但它们是等价的。
  • 好的,谢谢您的信息。但是为什么我的函数只是在空白中创建第一个列表的修改副本?
  • 空白[1] 必须是空白[0] 的修改副本,空白[2] 必须是空白[1] 的修改副本,依此类推。但是我的函数每次只是复制空白[0]并随机修改一个值

标签: python list function random


【解决方案1】:

你从1开始你的范围,当它们应该从0开始时,你总是从list_one复制并且永远不会更新它,因此它们都是原始列表的副本,而不是先前修改的列表,这是固定代码

import random
list_one=[1,2,3,4,5]
blank = []
def new_function(value):
    global list_one
    for i in range(value):
        list_copy = list_one[:]
        blank.append(list_copy)
        x=random.choice(blank[i])
        y=blank[i].index(x)
        blank[i][y]=x+1
        list_one = list_copy
    return blank
print new_function(4)

这给了我一个随机输出

[[2, 2, 3, 4, 5], [3, 2, 3, 4, 5], [3, 2, 3, 4, 6], [3, 2, 3, 5, 6]]

与您的描述相符。

另外,为什么不从列表中选择一个元素,为什么不选择一个随机索引然后修改它呢?

def new_function(value):
    global list_one
    for i in range(value):
        list_copy=list_one[:]
        blank.append(list_copy)
        x=random.randrange(len(list_copy))
        blank[i][x] += 1
        list_one = list_copy
    return blank

【讨论】:

    【解决方案2】:

    问题是您总是复制原始列表,而不是新列表。这很容易通过为新列表使用相同的名称来解决,因此,当循环再次出现时,新列表会被复制:

    import random
    
    def randomly_increment(seq, n):
        for _ in range(n):
            x = random.randrange(len(seq))
            seq = list(seq)
            seq[x] += 1
            yield seq
    

    我认为这是按预期工作的:

    >>> list(randomly_increment([1, 2, 3, 4, 5], 4))
    [[1, 2, 4, 4, 5], [1, 2, 4, 5, 5], [1, 2, 4, 5, 6], [1, 2, 4, 6, 6]]
    

    其他变化:

    • 这是一个生成器,而不是构建一个列表,它通常更灵活,更容易读/写。如果您需要一个列表,请按上述方法使用list() 封装调用。
    • 与其做一个随机的选择,然后找到它的地方来改变它,而是选择一个地方,然后改变它更有意义。这也避免了seq.index() 将返回与给定值匹配的第一个值,而不一定是“选择”值的问题。
    • 使用list(seq) 复制seq[:],如我的评论中所述。这更具可读性。

    【讨论】:

    • 哦,好吧,我明白了。我想这毕竟是我的问题!并感谢您的帮助!
    【解决方案3】:

    为了确保每次我会这样复制列表:

    from random import choice
    list_one=[1,2,3,4,5]
    
    def new_function(value):
    
        blank=[]
        blank.append(list_one)
    
        new_list = []
    
        for i in range(value):
            new_list = new_list[:] if new_list else list_one[:]
            new_list[choice(new_list)] += 1 
            blank.append(new_list)
        return blank
    
    print (new_function(4))
    

    【讨论】:

    • 您好,感谢您的信息。我的解释器说“列表”对象没有属性“复制”
    • 我正在运行 Python 3.3,无论如何我更正了 sn-p 以使用列表切片。
    猜你喜欢
    • 2011-10-23
    • 2015-04-25
    • 2011-02-02
    • 2013-06-10
    相关资源
    最近更新 更多