Ern*_*ari 5 python computational-geometry python-2.7
我行的列表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
Run Code Online (Sandbox Code Playgroud)
这是我的代码,但结果是错误的:
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)
Run Code Online (Sandbox Code Playgroud)
输出:
False
Run Code Online (Sandbox Code Playgroud)
您可以使用内置函数all来执行此操作,确保首先对列表内容进行排序,因为它们的顺序可能与生成的顺序不同itertools.combinations:
sLines = [tuple(sorted(l)) for l in Lines]
dataE = itertools.combinations('BCD', 2)
Run Code Online (Sandbox Code Playgroud)
现在您可以调用all它将检查中的每个值是否dataE存在于sLines:
all(l1 in sLines for l1 in dataE)
Run Code Online (Sandbox Code Playgroud)
哪个会返回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)
Run Code Online (Sandbox Code Playgroud)
现在进行的调用将检查是否Lines包含geometry:
check_geometry(Lines, 'BCD')
# returns True
check_geometry(Lines, 'ABE')
# returns False
Run Code Online (Sandbox Code Playgroud)
为了概括这一点,我们可以放弃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)
Run Code Online (Sandbox Code Playgroud)
这里的主要区别是:
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')]
Run Code Online (Sandbox Code Playgroud)
"BCDA"现在我们可以检查是否可以通过 中的线构造具有点的几何图形Lines:
check_geometry(Lines, "BCD")
# True
check_geometry(Lines, "BCDA")
# True
check_geometry(Lines, "BCDF")
# False
Run Code Online (Sandbox Code Playgroud)
注1:Lines可写为:
Lines=[('B', 'C'), ('D', 'A'), ('D', 'C'), ('A', 'B'), ('D', 'B')]
Run Code Online (Sandbox Code Playgroud)
括号()和逗号,在这里没有额外的作用,你可以删除它们:-)。
注 2:geometry的参数check_geometry可以是任何可迭代的(元组、列表、字符串):
check_geometry(lines, "BCD") == check_geometry(lines, ('B', 'C', 'D'))
Run Code Online (Sandbox Code Playgroud)
在这种情况下,创建并将 a 传递tuple给它似乎有些奇怪(唉,您可能有充分的理由这样做)。除非有特殊原因,我建议使用字符串作为参数的值geometry。