目前我这样做:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Run Code Online (Sandbox Code Playgroud)
但我想要一个表达式,我可以放在一个简单的if陈述中.是否有任何内置功能可以使这些代码看起来不那么笨拙?
any()False如果iterable为空,则返回,但如果不是,则可能会迭代所有项.我只需要它来检查第一项.
有人问我要做什么.我编写了一个执行SQL查询并生成结果的函数.有时当我调用此函数时,我只想知道查询是否返回任何内容并根据它做出决定.
字符串类的接口通常具有名为IsEmpty(VCL)或empty(STL)的方法.这是绝对合理的,因为它是一个特殊情况,但使用这些方法的代码通常必须否定这个谓词,这导致"光学(甚至心理)开销"(感叹号不是很明显,特别是在一个左括号后) ).例如,请参阅此(简化)代码:
/// format an optional time specification for output
std::string fmtTime(const std::string& start, const std::string& end)
{
std::string time;
if (!start.empty() || !end.empty()) {
if (!start.empty() && !end.empty()) {
time = "from "+start+" to "+end;
} else {
if (end.empty()) {
time = "since "+start;
} else {
time = "until "+end;
}
}
}
return time;
}
Run Code Online (Sandbox Code Playgroud)
它有四个否定,因为空案例是要跳过的.在设计界面时,我经常会观察到这种否定,这不是一个大问题,但它很烦人.我只想支持编写易于理解且易于阅读的代码.我希望你能理解我的观点.
也许我只是失明了:你如何解决上述问题?
编辑:在阅读了一些评论后,我认为原始代码使用System::AnsiString …
python生成器是列表的良好替代品,在大多数情况下,我希望检查空条件,这是普通生成器无法实现的.我正在尝试编写一个包装器,它将允许检查空状态,但仍然是懒惰的并且提供了生成器的好处.
class mygen:
def __init__(self,iterable):
self.iterable = (x for x in iterable)
self.peeked = False
self.peek = None
def __iter__(self):
if self.peeked:
yield self.peek
self.peeked = False
for val in self.iterable:
if self.peeked:
yield self.peek
self.peeked = False
yield val
if self.peeked:
yield self.peek
self.peeked = False
def __nonzero__(self):
if self.peeked:
return True
try:
self.peek = self.iterable.next()
self.peeked = True
return True
except:
return False
Run Code Online (Sandbox Code Playgroud)
样品用法:
def get_odd(l):
return mygen(x for x in l if x%2)
def print_odd(odd_nums): …Run Code Online (Sandbox Code Playgroud) 假设我循环遍历一个iterable,并希望在迭代器为空时采取一些操作.我能想到的两个最好的方法是:
for i in iterable:
# do_something
if not iterable:
# do_something_else
Run Code Online (Sandbox Code Playgroud)
和
empty = True
for i in iterable:
empty = False
# do_something
if empty:
# do_something_else
Run Code Online (Sandbox Code Playgroud)
第一个取决于可迭代是一个集合(当迭代被传递到循环所在的函数/方法时是无用的)而第二个集合empty在每次遍历循环时似乎很难看.
还有另一种我缺失的方式或者是最好的第二种方式吗?如果有一些我可以添加到循环语句中的子句会为我处理这个,就像elsemake not_found标志消失那样真的很酷.
我不是在寻找聪明的黑客.
我不是在寻找涉及大量代码的解决方案
我正在寻找一个简单的语言功能.我正在寻找一种清晰而pythonic的方法来迭代一个iterable并采取一些动作,如果iterable是空的,任何有经验的python程序员都会理解.如果我能在没有在每次迭代时设置标志的情况下这样做,那就太棒了.如果没有这样做的简单成语,那就算了吧.
如果迭代完成但没有被中断,则/ 子句中的else块被执行,所以我读了.forelsebreak
是否有一种语言结构可以让我写一些只有在for循环没有开始迭代时执行的东西?如果我正在使用tuple或list,我会做这样的事情:
if seq:
for x in seq:
# something
else:
# something else
Run Code Online (Sandbox Code Playgroud)
但是当我使用生成器时,我没有得到我想要的行为:
>>> g = (x for x in range(2))
>>> for x in g:
... print x
... else:
... print "done"
...
0
1
done # I don't want "done" here
>>> g = (x for x in range(2) if x > 1)
>>> if g:
... for x in g: …Run Code Online (Sandbox Code Playgroud) 我对使用生成器而不是列表感到非常惊讶。但我找不到这个问题的任何解决方案。
从生成器项中获取第一个和最后一个元素的有效方法是什么?因为使用列表我们可以只执行 lst[0] 和 lst[-1]
谢谢您的帮助。我无法提供任何代码,因为很明显这正是我想知道的:)
python ×6
coding-style ×2
generator ×2
iterator ×2
api ×1
c++ ×1
iterable ×1
python-2.7 ×1
readability ×1
string ×1