给定整数a,b使得a< b;和一些有序的可迭代整数序列seq
。确定a
和b
是否按顺序出现在seq
明显的第一步是:
假设 a< b(如果a> b,只需切换值)。
>>> idx = 0
>>> for i in range(0, len(l)):
... if a == l[i]:
... idx = i
...
>>> b == l[idx+1]
这感觉很笨拙。
例如,给定
>>> [1, 2, 3, 8]
如果a为1且b为3,则它们不相邻,如果b中的3为8,则为。
有些东西告诉我有更多的pythonic方法可以做到这一点,或者这是一个很好探索的问题,我错过了更清晰/更清晰的方法来接近它。
答案 0 :(得分:3)
使用任意缩减器来确定是否有任何相邻的对匹配(a,b):
>>> seq = [1, 2, 3, 8]
>>> a = 3
>>> b = 8
>>> any((seq[i], seq[i+1]) == (a,b) for i in range(len(seq)-1))
True
>>> b = 1
>>> any((seq[i], seq[i+1]) == (a,b) for i in range(len(seq)-1))
False
>>>
答案 1 :(得分:3)
使用 zip 的简短回答:
(a, b) in zip(seq[:-1], seq[1:])
当你被允许翻转
时,这是有效的(a, b) in zip(seq[:-1], seq[1:]) or (b, a) in zip(seq[:-1], seq[1:])
要使其逻辑正确,您可以先测试a in seq
。如果它通过,则应保持先前的测试。
有关zip
正在做什么的一些信息
>>> print seq
[1, 2, 3, 8]
>>> zip(seq[:-1], seq[1:])
[(1, 2), (2, 3), (3, 8)]
使用itertools包中的 izip 和 islice
from itertools import izip, islice
N = len(seq)
(a, b) in izip(islice(seq, 0, N - 1), islice(seq, 1, N))
答案 2 :(得分:2)
您可以遍历序列中的元素对,并检查一对是否包含a
和b
。使用itertools
中的pairwise
食谱:
>>> from itertools import tee
>>> def pairwise(iterable):
... x, y = tee(iterable)
... next(y, None)
... return zip(x, y)
...
>>> a, b, seq = 3, 8, [1, 2, 3, 8]
>>> (a, b) in pairwise(seq)
True
这对任意大型序列都很快(与列表切片解决方案不同)。
答案 3 :(得分:2)
答案 4 :(得分:1)
其他人正在实施与问题定义要实现的完全不同的东西。具体来说,我们应该做以下事情:
确定
b == l[i+1]
是否暗示i < len(l)
{/ 1}}a
即使在列表中也不需要b
或a
,并且(如果“有序”不是指“已排序”)b
和{{ 1}}可以在列表中多次显示。
要确定问题定义实际上要确定的内容,我们可以遍历所有相邻元素对并测试暗示是否成立:
if l and l[-1] == a:
# Problem definition doesn't say what to do.
shrug()
return all(x != a or y == b for (x, y) in zip(l[:-1], l[1:]))
如果我们 假设输入已排序,我们可以通过二分搜索做得更好:
import bisect
if l and l[-1] == a:
# We still don't know what to do for this case.
shrug()
possible_leftmost_a_index = bisect.bisect_left(l, a)
if possible_leftmost_a_index == len(a):
# All elements of l are lower than a.
return True
elif l[possible_leftmost_a_index] != a:
# a isn't in the list.
return True
elif l[possible_leftmost_a_index+1] == b:
# The implication holds. (We don't have to look for more occurrences of a,
# because bisect guarantees no a occurrences to the left, and everything to
# the right is greater than a.)
return True
else:
return False
答案 5 :(得分:1)
问题可分为两个子问题:
[a, b, c]
应转换为[(a, b), (b, c)]
。(x, y)
是否在步骤1中生成的序列中。您可以使用以下符号将iterable转换为一系列对:
def pairs(collection):
collection = iter(collection)
a = next(collection)
for b in collection:
yield a, b
a = b
collection
可以是列表,也可以是无限生成器。
要确定(x, y)
是否在pairs
的输出中,您只需执行以下操作:
(x, y) in pairs(seq)