Я пытаюсь сделать функцию, которая примет список, такой как:
l = [["A", 1, 2, 3, 4, 5],
["A", "A", 2, 3, 4, 5],
[1, 2, 3, 4, 5, 5],
["A", "A", "A", "A", "A", "A"],
["A", 3, "A", 4, "A", "A"],
[1, 3, 5, "A", 5, "A"]
]
и ключ, например "A". И предоставит список, содержащий int, в зависимости от того, сколько раз KEY появляется в 2D-списке в каждой ячейке 2x2. Так, например, функция
def count_in_grids(l, key):
вернусь
[3, 0, 0, 2, 2, 2, 1, 2, 3]
Пока у меня действительно плохой код, который я написал. У меня обычно возникают проблемы с управлением 2D-списками. Поскольку это фактически назначение, мне не разрешено использовать какую-либо библиотеку. Если кто-то может помочь мне понять и написать это, я буду глубоко этому благодарен.
Мой дрянной код, который я написал до сих пор:
def countInGrids(l, thing):
new_list = [] # created a final list that will be returned
count = 0
for line in range(0, len(l), 2): # Access lines
for el in range(0, line, 2): # Access elements
#count + count() of all elements in line[el] to line[el+1],
move 2 lines down and repeat.
count += line[line[el]:line[el]+1].count(thing)
count += line+1[line[el]:line[el]+1].count(thing)
new_list.append(count)
print(new_list)
return new_list
OUTPUT: строка 63, в countInGrids count + = line [line [el]: строка [el] +1]. Count (вещь) TypeError: объект 'int' не является индексируемым
PS: Если кому-то интересно, это мой первый семестр CS Lab
Это, вероятно, немного неуклюжий, но перечислить понимание всегда можно.
def countInGrid(grid, key):
return [sum([v[i:i+2].count(key) for v in grid[j:j+2]])
for j in range(0, len(grid), 2) for i in range(0, len(grid[0]), 2)]
Исходя из этого, то, что он использует для создания сетки 2x2, является [v[i:i+2] for v in grid[j:j+2]
. Это не очень эффективная операция, если вы делаете это во весь список списков несколько раз, но быстро записываете.
Чтобы подсчитать ключ, он сначала учитывается в каждой строке с помощью .count(key)
, а затем добавляет его для каждой из двух строк в вашей сетке 2x2, используя sum()
.
Последняя строка - это то, как вы выбираете, какую сетку 2x2 вы хотите посмотреть. Он указывает, где вы начнете и где закончите. Порядок i
и j
важен, если вы не хотите итерации по столбцам, а затем по строкам.
В понимании списка в основном есть все следующие небольшие компоненты, завернутые в более строгий синтаксис.
def count_row(v, key):
return v.count(key)
def count_grid(grid, key):
return sum(count_row(v, key) for v in grid)
def get_nxn(grid, i, j, n=2):
return [v[i:i+n] for v in grid[j:j+n]]
def iter_block_row(grid, j):
for i in range(0, len(grid[0]), 2):
yield get_nxn(grid, i, j)
def iter_grid(grid):
for j in range(0, len(grid), 2):
# In Python 3.3+, use
# yield from iter_block_row(grid, j)
for g in iter_block_row(grid, j):
yield g
def count_in_grid(grid, key):
return [count_grid(g, key) for g in iter_grid(grid)]
Размышление о больших проблемах, состоящих из небольших частей, помогает сделать их управляемыми с любым опытом. Также полезно видеть, что вам не нужны какие-либо дополнительные синтаксические сахара и языковые трюки для достижения той же цели чистым способом.
Обратите внимание, что срезы в get_nxn()
неэффективны. Это один из способов разложить проблему (и я думаю, что это самый простой способ мыслить концептуально), но это НЕ самый эффективный.
Обновление Я ошибался в работе get_nxn()
. Похоже, что куски списков в Python не копируют данные, даже в Python 2. 7+. Операция get_nxn()
выполняется в постоянное время по отношению к размеру grid
, и при этом происходит быстрое постоянное время.
Заманчиво попытаться найти решение с нарезкой и пониманием сразу с места в карьер, но я думаю, что риск путаницы достаточно высок, чтобы было нормально начать с наивного решения.
Первый шаг - найти все углы суб-квадратов:
1 . 2 . 3 .
. . . . . .
4 . 5 . 6 .
. . . . . .
7 . 8 . 9 .
. . . . . .
Это подсчет вложенного цикла на 2, где угловая ячейка находится в (row, col)
.
Учитывая подквадр, пересечение его ячеек - это еще одна пара вложенных циклов с шагом 1:
1 2 x . x .
3 4 . . . .
x . x . x .
. . . . . .
x . x . x .
. . . . . .
Здесь каждый элемент находится в (row + i, col + j)
где i
и j
- шаги внутреннего цикла.
После этого, это вопрос написания условного теста и добавления счетчика для каждого под-квадрата в список результатов.
Наконец, добавьте размер шага в качестве параметра по умолчанию, чтобы увеличить повторное использование.
Объединяя это:
def count_in_grids(l, key, size=2):
result = []
for row in range(0, len(l), size):
for col in range(0, len(l[row]), size):
result.append(0)
for i in range(size):
for j in range(size):
if key == l[row+i][col+j]:
result[-1] += 1
return result
print(count_in_grids(l, "A"))
Здесь нужно повторить тест.
for line in range(0, len(l), 2):
результатеline
становится целым числом. Но в вашем цикле вы пытаетесь проиндексировать его как массив или список. Это сообщение об ошибке здесь.