small code redundancy within while-loops (doesn't feel clean)
So, in Python (though I think it can be applied to many languages), I find myself with something like this quite often:
the_input = raw_input("what to print?\n")
while the_input != "quit":
print the_input
the_input = raw_input("what to print?\n")
Maybe I'm being too picky, but I don't like how the line the_input = raw_input("what to print?\n")
has to get repeated. It decreases maintainability and organization. But I don't see any workarou开发者_JAVA技巧nds for avoiding the duplicate code without further worsening the problem. In some languages, I could write something like this:
while ((the_input=raw_input("what to print?\n")) != "quit") {
print the_input
}
This is definitely not Pythonic, and Python doesn't even allow for assignment within loop conditions AFAIK.
This valid code fixes the redundancy,
while 1:
the_input = raw_input("what to print?\n")
if the_input == "quit":
break
print the_input
But doesn't feel quite right either. The while 1
implies that this loop will run forever; I'm using a loop, but giving it a fake condition and putting the real one inside it.
Am I being too picky? Is there a better way to do this? Perhaps there's some language construct designed for this that I don't know of?
Think iterators -- e.g., in this specific case:
for the_input in iter(lambda: raw_input('what to print?\n'), 'quit'):
print the_input
Most loops in Python, except at the very lowest levels of abstractions, are best implemented as for
loops with the help of some underling iterator which captures the "looping logic" -- the iter
built-in can help (like here), sometimes genexps (generator expressions) can, sometimes the standard library module itertools
comes to the rescue.
Most often you will choose to code custom generator functions (ones using yield
), or more occasionally (when you need really sophisticated state management) a custom iterator class (one defining the __iter__
special method as return self
, and next
[[or __next__
in the latest versions of Python]] to return "the next value from the iteration).
Capturing the looping logic apart from whatever it is that you do on the various items sequentially produced by the loop itself is the key abstraction-helper here!
精彩评论