Обрезать 2d-список, пока содержимое не образует прямоугольник (Python) - PullRequest
3 голосов
/ 26 мая 2020

В редакторе уровней, который я должен создать, мне нужно взять 2-й список с большим количеством пустых пробелов (0), вырезать и добавить к нему, пока не будет 0 снаружи, внутри все в порядке . Первое, что мне нужно сделать, это вырезать все лишние 0 с каждой стороны, например:

map = [
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
  [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
  [0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0],
  [0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0],
  [0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0],
  [0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0],
  [0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0],
  [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0],
  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]

def clipMap(map):
  """Need the code for"""

map = clipMap(map)

#map should now be:
  [1, 1, 1, 1, 1, 1, 1, 1],
  [1, 0, 0, 1, 0, 0, 1, 1],
  [1, 0, 0, 1, 0, 1, 0, 1],
  [1, 1, 1, 1, 1, 0, 0, 1],
  [1, 0, 1, 0, 0, 1, 0, 1],
  [1, 0, 1, 0, 0, 1, 0, 1],
  [1, 1, 1, 1, 1, 1, 1, 1]

Обратите внимание, что я использую только 1 и 0, когда в редакторе есть много разных блоков, которые в этом случае будет 1.

EDIT: Я пробовал это, но это было действительно ошибочно:

def clipMap(map):
  minX = 0
  minY = 0
  maxX = len(map[0])
  maxY = len(map)


  #Find min and max
  for y in map:
    for x in map[y]:
      if map[y][x] != 0:
        if x < minX:
          minX = x
        else if x > maxX:
          maxX = x

        if y < minY:
          minY = y
        else if y > maxY:
          maxY = y

  #remove them
  X = slice(minX, maxX)
  Y = slice(minY, maxY)
  map = map[Y]
  for y in map:
    map[y] = map[y][X]

  return map




1 Ответ

3 голосов
/ 26 мая 2020

Наивная версия может быть:

def truthy_idx(it):
    return next(i for i, x in enumerate(it) if x)

res = [x[truthy_idx(x):len(x)-truthy_idx(x[::-1])] for x in map if any(x)]

Это выбирает все строки, которые имеют хотя бы одно ненулевое значение в них, и обрезает каждую выбранную строку по ее левому и правому ненулевым элементам. Я использую функцию truthy_idx, чтобы получить первый ненулевой (правдивый) индекс в итерации, а также фрагмент, чтобы перевернуть список и получить последний индекс с помощью len(row) - truthy_idx(row[::-1]).

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

Кстати, вызов переменной map перезаписывает встроенную функцию.


Если вы можете использовать numpy, другой подход:

np.apply_along_axis(np.trim_zeros, 1, a[a.any(1)])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...