Как использовать списки для этого?

Amish Gaur спросил: 13 июня 2018 в 10:45 в: python-3.x

Я хочу ввести 2 числа: количество строк и количество столбцов. Затем я хочу использовать их для вывода матрицы, пронумерованной последовательно. Я хочу сделать это, используя понимание списка. Ниже приведен возможный вывод.

>>>> my_matrix = matrix_fill(3, 4)
>>>> my_matrix
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

Я использую следующий код для вывода списка последовательно нумерации:

def matrix_fill(num_rows, num_col):
     list=[i for i in range(num_col)]
     return (list)

Я не могу , однако, выясните, как сделать последовательный список чисел разбитыми на отдельные списки, как показано на выходе, основанном на num_rows.

3 ответа

Tomas Farias ответил: 13 июня 2018 в 11:02

Настройте понимание списка внутри другого, используйте itertools.count() для генерации последовательности:

import itertoolsrows = 3
cols = 4count_gen = itertools.count() # pass start=1 if you need the sequence to start at 1
my_matrix = [[next(count_gen) for c in range(cols)] for r in range(rows)]
print(my_matrix)
# prints: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]# As a function
def matrix_fill(rows, cols):
    count_gen = itertools.count()
    return [[next(count_gen) for c in range(cols)] for r in range(rows)]
Rory Daulton ответил: 13 июня 2018 в 11:13

Если вы использовали модуль numpy, этот метод чрезвычайно прост, без необходимости понимания списка.

my_matrix = np.arange(1, 13).reshape(3,4)

Печать переменной my_matrix показывает

[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
Ruan ответил: 13 июня 2018 в 11:20

Я не думаю, что для этого вам нужны itertools. Функция диапазона может сделать шаг в качестве параметра. Пример:

def matrix_fill(rows,cols):
    return [[x for x in range(1,rows*cols+1)][i:i+cols] for i in range(0,rows*cols,cols)]

И тогда он работает так, как ожидалось.

>>> matrix_fill(3,4)
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

Давайте немного разобьем это и поймем, что происходит.

>>> [x for x in range(1,3*4+1)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

Итак, что мы хотим сделать, это получить новый срез каждые четыре элемента.

>>> [x for x in range(1,3*4+1)][0:4]
[1, 2, 3, 4]>>> [x for x in range(1,3*4+1)][4:8]
[5, 6, 7, 8]>>> [x for x in range(1,3*4+1)][8:12]
[9, 10, 11, 12]

Итак, мы хотим перебрать элементы списка [x for x in range(1,3*4+1)] длины "rows cols" ( 3 * 4 ), создайте новый срез для каждого количества столбцов "cols" и сгруппируйте эти фрагменты под одним списком. Поэтому [[x for x in range(1,rows*cols+1)][i:i+cols] for i in range(0,rows*cols,cols)] является подходящим выражением.

Amish Gaur ответил: 13 июня 2018 в 11:10
Я был бы признателен, если бы вы могли объяснить, что происходит в (x для x в диапазоне (1, строки cols + 1)] [i: i + cols] для i в диапазоне (0, строки cols, cols), потому что я как бы потерян.
Ruan ответил: 13 июня 2018 в 11:21
Я отредактировал ответ, надеюсь, теперь он станет яснее.