Проверка того, что геометрия треугольника содержится в списке линий
У меня есть список линий Lines=([('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')]) и geometry = ('B', 'C', 'D') - это список точек, которые образуют треугольник (B,C,D). 
Я хочу проверить, можно ли настроить geometry из списка строк в Lines. Как я могу создать функцию для проверки этого статуса? True или False.
Пример функциональности с входными строками:
>> Lines=([('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B'),])
>> geometry1 = ('B', 'C', 'D')
>> check_geometry(Lines, geometry1)
   True
>> geometry2 = ('A', 'B', 'E')
>> check_geometry(Lines, geometry2)
   False
Это мой код, но результат неверный:
import itertools
def check_geometry(line, geometry):
    dataE = [set(x) for x in itertools.combinations(geometry, 2)]
    for data in dataE:
       if data not in line:
           return False
    return True 
Lines = [('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B'),]
geometry1 = ('B', 'C', 'D')
print check_geometry(Lines, geometry1)
Вывод:
False
2 ответа:
Для треугольников:
Вы можете использовать встроенный
allдля этого необходимо сначала отсортировать содержимое списка, так как их порядок может отличаться от порядка, сгенерированного изitertools.combinations:sLines = [tuple(sorted(l)) for l in Lines] dataE = itertools.combinations('BCD', 2)Теперь вы можете вызвать
all, который проверит, что каждое значение вdataEприсутствует вsLines:all(l1 in sLines for l1 in dataE)Который вернется
True.Итак, ваша функция
check_geometryможет выглядеть примерно так:def check_geometry(line, geometry): sLines = [tuple(sorted(l)) for l in line] dataE = itertools.combinations(geometry, 2) return all(l1 in sLines for l1 in dataE)Звонки сделаны будут сейчас проверьте, содержат ли
Linesgeometry:check_geometry(Lines, 'BCD') # returns True check_geometry(Lines, 'ABE') # returns False
Чуть более общее:
Чтобы немного обобщить это, мы можем отброситьitertools.combinationsи вместо этого использоватьzip. Следующее вносит некоторые соответствующие изменения в функцию, чтобы аккомодироватьzip, но выполняет аналогичные вещи:def check_geometry(line, geometry): sLines = [sorted(l) for l in line] dataE = [sorted(x) for x in zip(geometry, geometry[1:] + geometry[:1])] return all(l1 in sLines for l1 in dataE)Ключевое различие здесь:
dataEтеперь это список списков, содержащих результатzip(geometry, geometry[1:] + geometry[:1]). То, чтоzipделает в этом случае, это берет строку типа"BCDA"и ту же строку с первым элементом, добавленным в конецgeometry[1:] + geometry[:1](то есть"CDAB"), и создает записи, обозначающие стороны фигуры:Теперь мы можем проверить, что геометрия с точками>>> s = "BCDA" >>> s[1:] + s[:1] >>> 'CDAB' >>> list(zip(s, s[1:] + s[:1])) [('B', 'C'), ('C', 'D'), ('D', 'A'), ('A', 'B')]"BCDA"может быть построена линиями вLines:check_geometry(Lines, "BCD") # True check_geometry(Lines, "BCDA") # True check_geometry(Lines, "BCDF") # False
Примечание 1:
Linesможет быть записано как:Lines=[('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')]Скобки
()и запятая,здесь не имеют дополнительного эффекта, их можно отбросить :-) .Примечание 2 : параметр
geometryдляcheck_geometryможет быть любым iterable (кортежи, списки, строки):check_geometry(lines, "BCD") == check_geometry(lines, ('B', 'C', 'D'))Создание и передача
tupleему кажется несколько странным в этом случае (увы, у вас может быть хорошая причина для этого). Если этого не требуют причины, я бы предложил использовать строки в качестве значения параметраgeometry.
Хорошо, я буду использовать строки для моего ответа, тогда вы сможете настроить код под свои нужды.Я думаю, что A, B, C могут быть строкой или чем угодно, определяющим точку, которая задает линию
Идея состоит в том, чтобы сгенерировать все линии (представленные парой точек), которые мы должны найти вdef check_for_triangle(tri, lines): lines_needed = zip(tri, (tri[1], tri[2], tri[0])) return all(line in lines or line[::-1] in lines for line in lines_needed) lines=[('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')] tri1 = ('B', 'C', 'D') tri2 = ('A', 'B', 'E') print(check_for_triangle(tri1, lines)) # True print(check_for_triangle(tri2, lines)) # Falselinesдля данного треугольника сzip. После этого мы проверяем, можно ли найти все эти строки вlines. Проверка наline[::-1]также необходима, потому что строка('A', 'B')одинакова строка as('B', 'A').