将二维数组转换为二维数组会导致错误的数组值

时间:2016-04-16 04:32:31

标签: python arrays multidimensional-array

我的1-D阵列正确导入并正确显示,我的逻辑也适用于我手工操作,所以我不确定是什么问题。当我将1-D数组中的每个值复制到2-D时,它会进行奇怪的复制模式以及输入错误的值。

这是一维数组:

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

这是以下输出:

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
row:  0  col:  0
0
In loop... [[1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0]]
row:  0  col:  1
1
In loop... [[2, 0, 0, 0], [2, 0, 0, 0], [2, 0, 0, 0], [2, 0, 0, 0]]
row:  0  col:  2
2
In loop... [[3, 0, 0, 0], [3, 0, 0, 0], [3, 0, 0, 0], [3, 0, 0, 0]]
row:  0  col:  3
3
In loop... [[4, 0, 0, 0], [4, 0, 0, 0], [4, 0, 0, 0], [4, 0, 0, 0]]
row:  1  col:  0
4
In loop... [[4, 5, 0, 0], [4, 5, 0, 0], [4, 5, 0, 0], [4, 5, 0, 0]]
row:  1  col:  1
5
In loop... [[4, 6, 0, 0], [4, 6, 0, 0], [4, 6, 0, 0], [4, 6, 0, 0]]
row:  1  col:  2
6
In loop... [[4, 7, 0, 0], [4, 7, 0, 0], [4, 7, 0, 0], [4, 7, 0, 0]]
row:  1  col:  3
7
In loop... [[4, 8, 0, 0], [4, 8, 0, 0], [4, 8, 0, 0], [4, 8, 0, 0]]
row:  2  col:  0
8
In loop... [[4, 8, 9, 0], [4, 8, 9, 0], [4, 8, 9, 0], [4, 8, 9, 0]]
row:  2  col:  1
9
In loop... [[4, 8, 10, 0], [4, 8, 10, 0], [4, 8, 10, 0], [4, 8, 10, 0]]
row:  2  col:  2
10
In loop... [[4, 8, 11, 0], [4, 8, 11, 0], [4, 8, 11, 0], [4, 8, 11, 0]]
row:  2  col:  3
11
In loop... [[4, 8, 12, 0], [4, 8, 12, 0], [4, 8, 12, 0], [4, 8, 12, 0]]
row:  3  col:  0
12
In loop... [[4, 8, 12, 13], [4, 8, 12, 13], [4, 8, 12, 13], [4, 8, 12, 13]]
row:  3  col:  1
13
In loop... [[4, 8, 12, 14], [4, 8, 12, 14], [4, 8, 12, 14], [4, 8, 12, 14]]
row:  3  col:  2
14
In loop... [[4, 8, 12, 15], [4, 8, 12, 15], [4, 8, 12, 15], [4, 8, 12, 15]]
row:  3  col:  3
15
In loop... [[4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16]]
Before return... [[4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16]]

这是功能代码:

def makeTwoArr(array, height, width):
    print(array)
    newArray=[]
    line=[0]*width
    for i in range(height):
        newArray.append(line)
    location=0
    print(newArray)
    for row in range(height):
        for col in range(width):
            print("row: ",row," col: ",col);
            print(location)
##            #print(array[location])
            newArray[col][row]=array[location]
##            print(newArray)
            location+=1
            print("In loop...",newArray)

    print("Before return...",newArray)
    return newArray

我和我的计算机科学教授都无法弄清楚为什么这些值是错误的,或者为什么它会在错误的迭代中填充某些点。

3 个答案:

答案 0 :(得分:3)

当您使用line=[0]*width然后append(line)时,实际上会在同一行中创建多个引用,因此当您修改循环中的一行时,实际上会修改所有行。您需要实际创建不同的行,以便在分配期间通过引用在同一列表中的任何位置不会修改值。记住列表是 mutable 总是很重要的,并且附加相同的列表会创建对同一列表的引用。

顺便说一下,我猜你的(教育)目的是你需要以这种循环方式进行任务,但是如果你试图用标准库更加惯用,你可以使用iterzip解压缩以创建列表列表,尽管这只能确保您的原始列表具有正确的元素数量。这可以通过将相同的迭代器传递给zip所需的次数来解压缩整个序列。

new_arr = list(map(list,zip(*[iter(arr)]*4)))

输出:

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

答案 1 :(得分:2)

正如大金刚正确提到的,你正在创建对同一行的引用。此外,循环构造有点不正确。

def makeTwoArr(array, height, width):
    print(array)
    newArray=[[0 for x in range(width)] for x in range(height)] 
    print(newArray)
    row=0
    col=0

    # Use single loop where possible. Loop in a loop may hamper performance.
    for location in range( 0, len(array)):
        print("row: ",row," col: ",col);
        print(location)
        newArray[row][col]=array[location]
        col+=1
        if col == width:
            row+=1
            col=0
        print("In loop...",newArray)

    print("Before return...",newArray)
    return newArray

oldarr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

newarr = makeTwoArr(oldarr, 4, 4)
print "############"
print ("New Array is", newarr)
  

我尝试了一种不同的方法来循环源数组而不是目标。原因是有单循环而不是双循环。虽然两者都可以被认为是正确的。

     

请将此解决方案作为起点,而不是复制粘贴解决方案。

答案 2 :(得分:0)

我相信这种情况正在发生,因为new_array中的每一行实际上都指向同一个完整列表line

像这样更改你的代码,它应该有效:

def makeTwoArr(array, height, width):
    print(array)
    newArray=[]
    #line=[0]*width                    # DON'T DO THIS
    for i in range(height):
        newArray.append([0]*width)     # DO THIS INSTEAD
    location=0
    print(newArray)
    for row in range(height):
        for col in range(width):
            print("row: ",row," col: ",col);
            print(location)
            newArray[col][row]=array[location]
            print(newArray)
            location+=1
            print("In loop...",newArray)

    print("Before return...",newArray)
    return newArray