Возьмите 2D-список любых четных измерений и верните список, содержащий количество вещей для каждой сетки 2 X 2 (Python) - PullRequest
0 голосов
/ 21 сентября 2018

Я пытаюсь создать функцию, которая будет принимать список, такой как:

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

ВЫХОД: строка 63, в countInGrids count + =line [line [el]: line [el] +1] .count (вещь) TypeError: объект 'int' не подлежит подписке

PS: Если кому-то интересно, это мой 1-й семестр CS Lab

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Очень заманчиво попробовать найти решение с помощью нарезки и понимания сразу, но я думаю, что риск путаницы достаточно высок, чтобы можно было начинать с наивного решения.

Первый шаг -Найдите все углы субквадрат:

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"))

Вот repl для проверкис.

0 голосов
/ 21 сентября 2018

Это, вероятно, немного неуклюже, но списки всегда доступны.

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), а затем складывает его для каждой из 2 строк в сетке 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, и при этом это быстрое постоянное время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...