检测Python循环中的值更改

时间:2015-03-06 23:37:57

标签: python

这是我经常使用的模式:

last_value = None

while <some_condition>:
    <get current_value from somewhere>
    if last_value != current_value:
       <do something>

    last_value = current_value

一个应用示例是在一个人的姓氏发生变化时在报告中打印标题。

整个last_value / current_value对我来说总是显得笨拙。有没有更好的方法在Python中编写代码?

3 个答案:

答案 0 :(得分:3)

我同意你的模式很有意义。

但为了好玩,你可以做类似的事情:

class ValueCache(object):
    def __init__(self, val=None):
        self.val = val

    def update(self, new):
        if self.val == new:
            return False
        else:
            self.val = new
            return True

然后你的循环看起来像:

val = ValueCache()
while <some_condition>:    
    if val.update(<get current_value from somewhere>):
        <do something>

例如

import time
t = ValueCache()
while True:
    if t.update(time.time()):
        print("Cache Updated!")

如果您将time.time()更改为某个静态对象,例如“Foo”,您会看到“Cache Updated!”只出现一次(当它最初从None设置为“Foo”时)。

强制性现实程序员注意:不要这样做。我不能轻易找到在实践中这样做的好理由。它不仅增加了行数,还增加了复杂性。

(灵感来自Alex Martelli's Assign and Test Recipe

答案 1 :(得分:3)

我认为模式非常清晰,但您可以使用生成器函数来隐藏last_value / current_value事物。

def value_change_iterator(iterable):
    last_x = None
    for x in iterable:
        if x != last_x:
            yield x
        last_x = x

for x in value_change_iterator([1, 1, 2, 2, 3, 3, 4]):
    print(x)

打印

1
2
3
4

答案 2 :(得分:2)

另一个灵感来自@jedwards答案的另一个选择灵感来自Alex Martelli的配方(这一个保留了当前和最后的值,并允许你使用None作为初始值,如果你如此倾向,也改变了来自语义的语义我并不特别喜欢其他语义我不确定我是否也喜欢):

class undefined:
    pass

class ValueCache:
    def __init__(self, value=undefined):
        self.current_value = value
        self.last_value = undefined
        self._is_changed = False

    @property
    def is_changed(self):
        is_changed = self._is_changed
        self._is_changed = False
        return is_changed

    def update(self, new_value):
        self._is_changed = (new_value != self.current_value)
        if self._is_changed:
            self.last_value = self.current_value
            self.current_value = new_value

示例:

>>> v = ValueCache()
>>> v.update(1)
>>> v.is_changed
True
>>> v.is_changed is False
False
>>> v.update(2)
>>> v.is_changed
True
>>> v.is_changed
False

或者在你的情况下:

t = ValueCache()
while True:
    t.update(time.time())
    if t.is_changed:
        print("Cache updated!")

同样的强制性现实程序员注释适用。