我想测试某个值是否属于使用迭代器生成的数字序列。当然,当值 属于序列时,可以在满足该值时立即停止。但当它不时,我想这就是问题出现的时候。
然而,可以使用附加信息(例如,序列正在增加)。
考虑斐波那契的例子:
class FibonacciIterator(object):
def __init__(self):
self.mem = [0, 1]
def __next__(self):
curr = self.mem[0]
new = self.mem[0]+self.mem[1]
self.mem[0] = self.mem[1]
self.mem[1] = new
return curr
class Fibonacci(object):
def __iter__(self):
return FibonacciIterator()
如果有人测试8
是否属于序列,那么一切都很好:
>>> fib = Fibonacci()
>>> 8 in fib
True
但是,如果一个测试10
(不属于序列)那么
>>> 10 in fib
...
永远不会终止。但是,可以通过在10
到达8
之后观察13
并且因为序列正在增加然后not 10 in fib
来轻松确定in
不在序列中。
在Python中有没有很好的方法来实现10 in fib
的这种行为,以便var collapsed: Bool {
didSet {
view.setNeedsUpdateConstraints()
}
}
@IBAction func onButtonClick(sender: UISwitch) {
view.layoutIfNeeded()
collapsed = !collapsed
UIView.animate(withDuration: 0.3) {
view.layoutIfNeeded()
}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
view.setNeedsUpdateConstraints()
}
override func updateViewConstraints() {
constraint1.isActive = !collapsed
constraint2.isActive = collapsed
super.updateViewConstraints()
}
终止?
答案 0 :(得分:1)
简单的解决方案是实现一个只迭代迭代器副本的__contains__
方法:
class FibonacciIterator(object):
def __init__(self):
self.mem = [0, 1]
def __iter__(self):
return self
def __contains__(self, value):
testit = FibonacciIterator()
testit.mem = list(self.mem) # copy
for item in testit:
if item == value:
return True
if item > value:
return False
def __next__(self):
curr = self.mem[0]
self.mem = self.mem[1], sum(self.mem)
return curr
class Fibonacci(object):
def __iter__(self):
return FibonacciIterator()
def __contains__(self, value):
return value in iter(self)
然而,还有另一种方法可以确定数字是否是斐波纳契数:如果(5*n**2 + 4)
或(5*n**2 – 4)
或两者都是完美的正方形(整数的平方)。
我将使用this answer中的方法来实现is_square
函数:
def is_square(apositiveint):
# Source: https://stackoverflow.com/a/2489519/5393381
# Credit: Alex Martelli
x = apositiveint // 2
seen = {x}
while x * x != apositiveint:
x = (x + (apositiveint // x)) // 2
if x in seen:
return False
seen.add(x)
return True
class FibonacciIterator(object):
def __init__(self):
self.mem = [0, 1]
def __iter__(self):
return self
def __contains__(self, value):
if value < self.mem[0]:
return False
else:
# Just check if at least one of both is a perfect square
value_squared_times_five = 5*value**2
return is_square(value_squared_times_five + 4) or is_square(value_squared_times_five - 4)
def __next__(self):
curr = self.mem[0]
self.mem = self.mem[1], sum(self.mem)
return curr
class Fibonacci(object):
def __iter__(self):
return FibonacciIterator()
def __contains__(self, value):
return value in iter(self)