Мне нужен файл .txt для чтения, и я нахожу определенный шаблон T, а именно T, расположенные в виде перекрестного шаблона.

Вот что я сделал до сих пор, и его результат при печати ниже:

def find_treasure(mapfile):
    lst = []
    with open(mapfile, 'r') as rf:
        for line in rf:
            lst.append(line.split())
    print(lst)

Вывод Моя первоначальная идея заключалась в том, чтобы сделать что-то вроде использования двух циклов for для просмотра каждого элемента в списке, а затем просмотра каждой буквы / символа в самом элементе, но я продолжал получать ошибки диапазона индекса списка или он вообще не работал.

for i in range(len(lst)):
    for j in range(len(lst[i])):
        if lst[i][j] == 'T':
            print('WHy')
        else:
            print('why am i here why')

Ребята, у вас есть какой-нибудь совет?

РЕДАКТИРОВАТЬ: Пример ввода:

WWWWWWWWWWWWWWWWWWWWWWW.TTT..^^^^...WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...T..^^^^....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWW..T.....^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWWW........^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^....T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^^.....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^......WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW....^^......WWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^.....WWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW............WWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWW....T......WWWWWWWWWWWWW
WWWWW...WWWWWWWWWWWWW..T.T.....WWWWWWWWWWWWW
WWWW..TTT.WWWWWWWWWWW...T.....WWWWWWWWWWWWWW
WWWWW.......WWWWWWWWWWW......WWWWWWWWWWWWWWW
WWWWWWWW...T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWW....WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWW.T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWW.WWWWWWWWWW.....WWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW....T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW.TTT..WWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW..T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...WWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
W: WATER                                    
T: TREE                                     
.: GRASS                                    
^: MOUNTAIN 

Ожидаемый результат: (21,25)

0
giddo244 7 Окт 2020 в 18:48

4 ответа

Лучший ответ

Боюсь, что ошибка, которую вы получаете, не вызвана каким-либо кодом, которым вы поделились, ваш цикл работает отлично (кроме line.split() разделения пробелами, которых нет в вашем файле, вам, вероятно, понадобится {{ X1}} или просто line для разделения по каждому символу)

Этот скрипт запускается без ошибок, демонстрируя, что ваша проблема находится в какой-то другой части вашего кода:

import io

mock_file = io.StringIO("""WWWWWWWWWWWWWWWWWWWWWWW.TTT..^^^^...WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...T..^^^^....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWW..T.....^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWWW........^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^....T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^^.....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^......WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW....^^......WWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^.....WWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW............WWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWW....T......WWWWWWWWWWWWW
WWWWW...WWWWWWWWWWWWW..T.T.....WWWWWWWWWWWWW
WWWW..TTT.WWWWWWWWWWW...T.....WWWWWWWWWWWWWW
WWWWW.......WWWWWWWWWWW......WWWWWWWWWWWWWWW
WWWWWWWW...T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWW....WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWW.T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWW.WWWWWWWWWW.....WWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW....T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW.TTT..WWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW..T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...WWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
W: WATER                                    
T: TREE                                     
.: GRASS                                    
^: MOUNTAIN""")

def find_treasure(mapfile):
    lst = []
    with mapfile as rf:
        for line in rf:
            lst.append(line.split(""))
    print(lst)
    
    for i in range(len(lst)):
        for j in range(len(lst[i])):
            if lst[i][j] == 'T':
                print('WHy')
            else:
                print('why am i here why')

find_treasure(mock_file)

По этой причине я хотел бы проверить, что переменная lst одинакова в двух упомянутых разделах кода, потому что ошибки диапазона могут возникать только в чем-то отличном от того, что вы показали.

0
Tadhg McDonald-Jensen 7 Окт 2020 в 16:49

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

Мы ищем "T", где есть дополнительные "T" с заданными смещениями, которые можно вычислить по длине линии.

Полученное совпадение будет непосредственно перед "T" в верхней части фигуры. Строка / столбец результата может быть рассчитана исходя из этой позиции и длины строки.

import re

with open('map.txt') as f:
    content = f.read()

line_length = content.index('\n') + 1

treasure = re.compile(rf'''
(?=                                    # start look-ahead
    \bT\b     .{{{line_length - 2}}}   #   free-standing  "T"  and fixed offset
   \bTTT\b    .{{{line_length - 2}}}   #   free-standing "TTT" and fixed offset
    \bT\b                              #   free-standing  "T"
)                                      # end look-ahead
''', re.S + re.X)

for m in treasure.finditer(content):
    pos = m.span()[0]
    line = pos // line_length + 2
    col = pos % line_length + 1
    print(line, col)

В вашем примере карты клад можно найти в 22 26.

Примечания

  • Я использую строку формата f'...{python expression}...', чтобы получить смещение в регулярном выражении.
  • Это не считывает файл построчно, а считывает его все в одну большую строку.
  • Режим re.S позволяет . сопоставлять символы новой строки (обычно это не так).
  • Режим re.X позволяет использовать пробелы и комментарии в регулярном выражении, что делает его более управляемым.
0
Tomalak 8 Окт 2020 в 10:20

Это не полный ответ, но я вижу две проблемы в вашем коде.

Во-первых, как упоминает Tadhg, ваш find_treasure не возвращает никакого значения, которое могло бы быть вызывая range errors.

Как только вы подключите это, ваш другой блок останется. И причина того, что вы достигли своего оператора why am i here why, заключается в том, что метод split() без параметра separator просто разделяет blank spaces. Если вы хотите отделить каждое значение от строки, вы должны использовать lst.append(list(line)), это создаст матрицу со всеми элементами вашего ввода, к которым будет осуществляться доступ с помощью mat[][]

Надеюсь, это вам поможет =).

1
bench 7 Окт 2020 в 16:48

Я предполагаю, что под "буквами T крест-накрест" вы подразумеваете следующее:

*T*
TTT
*T*

Где * - это что угодно, кроме T.

Таким образом, чтобы идентифицировать перекрестный узор с центром в местоположении lst[i][j], все окружающие его индексы должны быть равны T.

def isCrossAt(lst, i, j):
    return lst[i - 1][j] == 'T' and \
           lst[i + 1][j] == 'T' and \
           lst[i][j - 1] == 'T' and \
           lst[i][j + 1] == 'T' and \
           lst[i][j] == 'T'

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

def findCrosses(lst):
    for i in range(1, len(lst) - 1):
        row = lst[i]
        for j in range(1, len(row) - 1):
            # Copy the isCrossAt logic here to save a function call
            foundCross = lst[i - 1][j] == 'T' and \
                         lst[i + 1][j] == 'T' and \
                         lst[i][j - 1] == 'T' and \
                         lst[i][j + 1] == 'T' and \
                         lst[i][j] == 'T'
            if foundCross:
                return (i, j)

Давайте проверим это с помощью вашей строки.

lst = """WWWWWWWWWWWWWWWWWWWWWWW.TTT..^^^^...WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...T..^^^^....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWW..T.....^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWWW........^^^^..T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^....T.WWWWWWW
WWWWWWWWWWWWWWWWWWWW........^^^......WWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^^.....WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW.....^^^......WWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW....^^......WWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW......^.....WWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW............WWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWW....T......WWWWWWWWWWWWW
WWWWW...WWWWWWWWWWWWW..T.T.....WWWWWWWWWWWWW
WWWW..TTT.WWWWWWWWWWW...T.....WWWWWWWWWWWWWW
WWWWW.......WWWWWWWWWWW......WWWWWWWWWWWWWWW
WWWWWWWW...T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWW....WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWW.T.WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWW.WWWWWWWWWW.....WWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWW....T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW.TTT..WWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWW..T..WWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWW...WWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW""".split('\n')

# Now lst is a list of strings, but that doesn't matter 
# because we can obtain characters in a string just like elements in a list
# duck typing FTW!

findCrosses(lst)

# Out: (21, 25)
1
Pranav Hosangadi 7 Окт 2020 в 16:56