Python 如何在不复制的情况下更改列表列表?
我有一个矩阵,在列表列表中给出:Python 如何在不复制的情况下更改列表列表?,python,list,Python,List,我有一个矩阵,在列表列表中给出: board = [[1, 0, 0, 1], [-1, -1, 1, 1], [0, 0, 0, 0]] 我想做的是改变董事会,但不复制。 我想将其更改为一个列板: def foo(board): change board to columns board board = foo(board) 结果是: board = [[1, -1, 0], [0, -1, 0], [0, 1, 0], [1, 1, 0]] 问题是它创建了一个同名(boar
board = [[1, 0, 0, 1], [-1, -1, 1, 1], [0, 0, 0, 0]]
我想做的是改变董事会,但不复制。
我想将其更改为一个列板:
def foo(board):
change board to columns board
board = foo(board)
结果是:
board = [[1, -1, 0], [0, -1, 0], [0, 1, 0], [1, 1, 0]]
问题是它创建了一个同名(board)的新变量,并且不更改原始board
我需要改变原来的董事会,因为我需要在不同的地方使用它之后
不能归还董事会,因为我会很乐意不去想它(不允许)
甚至尝试过:
a = foo(board)
board.clear()
board += a
这应该是可行的,但由于某种原因我的程序出现了错误。任何被称为换位的帮助都将不胜感激。您可以通过将2D列表扩展到zip并将每个项目转换为列表来实现这一点:
board = [[1, 0, 0, 1], [-1, -1, 1, 1], [0, 0, 0, 0]]
bid = id(board)
print(board)
# The posed question insists on mutating board so here it is.
for i, item in enumerate(list(item) for item in zip(*board)):
try:
board[i] = item
except IndexError:
board.append(item)
print(bid == id(board))
print(board)
输出:
[[1, 0, 0, 1], [-1, -1, 1, 1], [0, 0, 0, 0]]
True
[[1, -1, 0], [0, -1, 0], [0, 1, 0], [1, 1, 0]]
.您可以在适当的位置执行此操作,但由于它改变了电路板的整个结构(子列表的数量等),因此它没有多大意义,似乎有点不自然。如果唯一的问题是有其他引用指向同一块板,则可以分配给切片板[:]
,以使用新板覆盖板的所有内容,而无需将新值分配给板本身
def swap(b):
return list(map(list, zip(*b)))
>>> board = [[1, 0, 0, 1], [-1, -1, 1, 1], [0, 0, 0, 0]]
>>> also_board = board
>>> board[:] = swap(board)
>>> also_board
[[1, -1, 0], [0, -1, 0], [0, 1, 0], [1, 1, 0]]
从记忆的角度来看,这是不合适的,但出于你的目的,它应该会起作用。只是为了好玩。
def transpose(matrix):
rows = len(matrix)
if rows < 1:
raise ValueError("matrix has to have at least one row")
rowlen = len(matrix[0])
if rowlen == 0:
raise ValueError("rows must not be empty")
if rowlen == 1 and rows == 1:
return
for i in range(1, rows):
if len(matrix[i]) != rowlen:
raise ValueError("rows must have the same lenght")
index = 0
while index < rowlen:
newrow = []
for c in range(rows):
newrow.append(matrix[c].pop(0))
matrix.append(newrow)
index += 1
if index == rowlen:
while(len(matrix[0]) == 0):
matrix.pop(0)
board = [[1,0,0,1], [-1,-1,1,1], [0,0,0,0]]
print("id|{}: {}".format(id(board), board))
print("transposing...")
transpose(board)
print("id|{}: {}".format(id(board), board))
def转置(矩阵):
行=len(矩阵)
如果行数小于1:
raise VALUERROR(“矩阵必须至少有一行”)
rowlen=len(矩阵[0])
如果rowlen==0:
raise VALUERROR(“行不能为空”)
如果rowlen==1且rows==1:
返回
对于范围内的i(1行):
如果len(矩阵[i])!=罗伦:
raise VALUERROR(“行必须具有相同的长度”)
索引=0
当索引
输出
id | 140328172362568:[1,0,0,1],-1,-1,1,1],[0,0,0,0]]
转置
id | 140328172362568:[1,-1,0],[0,-1,0],[0,1,0],[1,1,0]]
速度非常慢,最好坚持使用zip你可以做board[:]=foo(board)
你说的“由于某种原因使我的程序出错”是什么意思?您遇到了什么错误?虽然可以从foo()
函数内部修改列表,但这可能不是解决原始问题的最佳方法。这样的副作用导致很难发现bug,因为值会意外更改。你能提供更多关于你想在这里做什么的背景吗?@AndrejKesely board[:]很好,谢谢!实际上尝试了一种不同的方法,但这一种better@Personman似乎我有另一个类似的问题,这就是为什么它窃听我的程序,没有收到错误,只是编辑错误的结果。同一块板。更新。更多代码。现在,董事会已经发生了变化,而不是被取代。带有突变的代码比用board=[list(item)for item in zip(*board)]
替换电路板的时间长一倍以上,这是公认答案中list(map(list,zip(*b))
的综合等价物。通过Jupyter笔记本中的timeit进行检查:每个循环12.2µs±47 ns(平均±标准偏差7次,每个循环100000次),而每个循环5.89µs±23.5 ns(平均±标准偏差7次,每个循环100000次)board[:]
在接受的答案中创建一个新的电路板。它有一个不同的id。上面的评论是对删除的评论的回应,该评论指出,存在的答案board=[zip(*board)中项目的列表(项目)]
不会更新board中的现有项目。