Недавно я начал изучать 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
Я пытался изменить оператор "count" в "crescentOrderArray2", но безуспешно. Я ожидал, что способ будет повторяться каждый раз, когда он добавляет «количество».
Итак, возможно, с выражением присваивания, но вам, вероятно, следует просто придерживаться своего цикла for. Вы не должны думать о включении списков как об альтернативном синтаксисе для циклов for. Понимание списков предназначено для сопоставления операций фильтрации, которые создают списки. В этом конкретном случае вы можете выразить это так, как показано в ответе ниже.
попробуйте это, это самый компактный способ:
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
не обновляется в вашем понимании списка. Просто используйте значения из генераторов диапазона:
arr = [[row*cols+col for col in range(1, cols+1)] for row in range(rows)]
Это создаст 2D-массив размера rows*cols
, где верхнее левое значение равно нулю, а затем увеличивается на единицу для каждой ячейки, идущей вправо.
Но нет никакой реальной причины делать это в как можно меньшем количестве строк. Пишите код так, чтобы его можно было прочитать.
Это не совсем правильно, так как значения начинаются с 0 вместо 1.
Ваша переменная 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]]
Используйте 2 объекта диапазона. Один повторяет начальный счетчик для каждой строки, а другой расширяет значения столбца.
def crescentOrderArray3(rows, columns):
return [list(range(i, i+columns))
for i in range(1, rows*columns+1, columns)]
Нет, в написанном вами коде переменная 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)]
Кстати,
.extend([count])
должно быть просто.append(count)