在Python中查找列表边界
给定一系列点(通过路径算法找到的),我想知道进出某个区域的点。区域外的点用 None
表示。比如,一个路径可以是 [None, 1, 2, None, 3, 4, 5, None]
,这个路径的结果应该是 [(1,2), (3,5)]
。对于一个特殊情况 [1, 2, None]
,结果应该是 [(None, 2)]
;而对于镜像情况 [None, 1, 2]
,结果应该是 [(1, None)]
。
如果不考虑最后两个特殊情况,我得到了:
[(systems[0], systems[-1]) if not outside else None
for outside, systems in [(o, list(sys))
for o, sys in groupby(path, lambda x: x is None)]]
或者通过 IRC:
def find_borders(L):
it = iter(L)
for item in it:
if item is None:
continue
start = item
end = item
for item in it:
if item is None:
break
end = item
yield (start, end)
通过IRC的解决方案,开头加上 None
很简单,但在结尾加上几乎是不可能的,除非对 iter
进行一次 peek
操作。
我该如何实现第二个特殊情况 [None, 1,2]
=> [(1, None)]
?
我创建了一个应该有效的解决方案,但实际上并没有。它给我抛出了一个 IndexError
,因为 systems
是一个空列表,这不应该发生,因为 groupby
保证不会分组成一个空列表。
def find_borders(path):
grouped = list(groupby(path, lambda x: x is None))
for index, (o, sys) in enumerate(grouped):
systems = list(sys)
if index == 0:
yield (None, systems[-1])
elif index == len(grouped)-1:
yield (systems[0], None)
else:
yield (systems[0], systems[-1])
2 个回答
0
更优雅的写法:
def find_borders(L):
entries = []
exits = []
if L[0] is not None:
entries.append(None)
for i in range(len(L[:-2])):
if L[i] is None:
entries.append(L[i+1])
if L[i+2] is None:
exits.append(L[i+1])
if L[-1] is not None:
exits.append(None)
return zip(entries, exits)
2
tests = [
[None, 1, 2, None, 3, 4, 5, None],
[1, 2, None, 3, 4, 5, None],
[None,1, 2, None, 3, 4, 5],
[1, 2, None, 3, 4, 5],
[1, 2, None],
[None, 1, 2],
]
def find_borders(L):
it = iter(L)
start_none = False
for item in it:
if item is None:
start_none = True
continue
if start_none:
start = item
else:
start = None
end = item
end_none = False
for item in it:
if item is None:
end_none = True
break
end = item
if not end_none:
end = None
yield (start, end)
start_none = True
for t in tests:
print
print t
for x in find_borders(t):
print x
[None, 1, 2, None, 3, 4, 5, None]
(1, 2)
(3, 5)
[1, 2, None, 3, 4, 5, None]
(None, 2)
(3, 5)
[None, 1, 2, None, 3, 4, 5]
(1, 2)
(3, None)
[1, 2, None, 3, 4, 5]
(None, 2)
(3, None)
[1, 2, None]
(None, 2)
[None, 1, 2]
(1, None)
结果