具有紧凑嵌套循环的 2D 列表



我最近开始学习python,并陷入了语法困境。有没有办法做这个代码冰块的作用:

def crescentOrderArray1(rows, columns):
arr = [[] for i in range(rows)]
count = 1
for row in range(rows):
for colum in range(columns):
arr[row].extend([count])
count = count + 1
return arr 

使用谨慎的语法,例如

def crescentOrderArray2(rows, columns):
count = 1
arr = [[count for i in range(rows)] for i in range(rows)]
return arr 

我尝试修改"crescentOrderArray2"中的"count"语句,但没有成功。我期待每次添加"计数"时都有一种方法进行迭代

使用 2 个范围对象。一个迭代每行的开始计数,另一个扩展为其列值。

def crescentOrderArray3(rows, columns):
return [list(range(i, i+columns)) 
for i in range(1, rows*columns+1, columns)]

试试这个,这是最紧凑的方式:

def crescent_order_array(rows, columns):
return [[i+j for i in range(1, columns+1)] for j in range(0, rows*columns, columns)]

您的count变量不会递增。幸运的是,您可以使用 i 和 j 值来计算计数应该是多少。请参阅下面的输出。

def crescentOrderArray1(rows, columns):
arr = [[] for i in range(rows)]
count = 1
for row in range(rows):
for colum in range(columns):
arr[row].extend([count])
count = count + 1
return arr 
def crescentOrderArray2(rows, columns):
arr = [[j+1 + cols*i for j in range(columns)] for i in range(rows)]
return arr
rows,cols = (3,5)
print(crescentOrderArray1(rows,cols))
print(crescentOrderArray2(rows,cols))
>>>[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]
>>>[[1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15]]

不,在您编写的代码中,第一行的count变量与第二行的count变量不同。

第二行使用列表推导表达式中的局部变量count,此嵌套count阴影第一行上定义的变量。

def crescentOrderArray2(rows, columns):
count = 1
arr = [[count for i in range(rows)] for i in range(rows)]
return arr 

将代码重写为更惯用形式的一种可能方法是使用列表推导式和帮助程序函数chunks将列表拆分为大小相等的块:

def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]

def crescentOrderArray2(rows, columns):
return [list(x) for x in chunks(range(1, rows*columns), columns)]

您的count变量不会在列表理解中更新。只需使用范围生成器中的值:

arr = [[row*cols+col for col in range(1, cols+1)] for row in range(rows)]

这将产生一个大小为rows*cols的 2D 数组,左上角的值为零,然后向右的每个单元格递增一个。

但是没有真正的理由在尽可能少的行中做到这一点。编写代码,使其可读。