“为了”循环第一次迭代
我想询问是否有一种优雅的 pythonic 方式在第一次循环迭代中执行某些函数。 我能想到的唯一可能性是:
first = True
for member in something.get():
if first:
root.copy(member)
first = False
else:
somewhereElse.copy(member)
foo(member)
I would like to inquire if there is an elegant pythonic way of executing some function on the first loop iteration.
The only possibility I can think of is:
first = True
for member in something.get():
if first:
root.copy(member)
first = False
else:
somewhereElse.copy(member)
foo(member)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
像这样的东西应该有效。
但是,我强烈建议您考虑一下您的代码,看看您是否真的必须这样做,因为它有点“脏”。更好的方法是预先获取需要特殊处理的元素,然后对循环中的所有其他元素进行常规处理。
我认为不这样做的唯一原因是为了从生成器表达式中获得一个大列表(您不想预先获取它,因为它不适合内存),或类似的情况。
Something like this should work.
However, I would strongly recommend thinking about your code to see if you really have to do it this way, because it's sort of "dirty". Better would be to fetch the element that needs special handling up front, then do regular handling for all the others in the loop.
The only reason I could see for not doing it this way is for a big list you'd be getting from a generator expression (which you wouldn't want to fetch up front because it wouldn't fit in memory), or similar situations.
对于头尾设计模式,您有多种选择。
或者
人们抱怨这在某种程度上不是“干”的,因为“冗余的 foo(member)”代码。这是一个荒谬的说法。如果这是真的,那么所有功能只能使用一次。如果只能有一个引用,那么定义函数还有什么意义呢?
You have several choices for the Head-Tail design pattern.
Or this
People whine that this is somehow not "DRY" because the "redundant foo(member)" code. That's a ridiculous claim. If that was true then all functions could only be used once. What's the point of defining a function if you can only have one reference?
怎么样:
或者也许:
索引方法的文档。
how about:
or maybe:
Documentation of index-method.
这是可行的:
不过,在大多数情况下,我建议只迭代
whatever[1:]
并在循环外执行根本操作;这通常更具可读性。当然,取决于您的用例。This works:
In most cases, though, I'd suggest just iterating over
whatever[1:]
and doing the root thing outside the loop; that's usually more readable. Depends on your use case, of course.在这里,我可以使用一个看起来“pertty”的 Pythonic 习语。尽管如此,我很可能会使用您在提出问题时建议的形式,只是为了让代码保持更明显,尽管不太优雅。
(抱歉 - 我发布的第一个在编辑之前,表单无法工作,我忘记了实际获取“复制”对象的迭代器)
Here, I could come with a Pythonic idiom that can look "pertty". Although, most likely I'd use the form you suggested in asking the question, just for the code to remain more obvious, though less elegant.
(sorry - the first I posted, before editing, form would not work, I had forgotten to actually get an iterator for the 'copy' object)
我认为这非常优雅,但对于它的作用来说可能太复杂了......
I think this is quite elegant, but maybe too convoluted for what it does...
如果something.get()迭代某些东西,你也可以这样做:
If something.get() iterates over something, you can do it also as follows:
我认为第一个 S.Lott 解决方案是最好的,但是如果您使用的是最近的 python (>= 2.6 我认为,因为 izip_longest 在该版本之前似乎不可用),那么还有另一种选择,可以让您做不同的事情第一个元素和后续元素,并且可以轻松修改以对第一个、第二个、第三个元素执行不同的操作...。
I think the first S.Lott solution is the best, but there's another choice if you're using a pretty recent python (>= 2.6 I think, since izip_longest doesn't seem available before that version) that lets doing different things for the first element and successive one, and can be easily modified to do distinct operations for 1st, 2nd, 3rd element... as well.
使用
iter
并使用第一个元素怎么样?编辑:回到OP的问题,您要对所有元素执行一个常见操作,然后对第一个元素执行一个操作,对其余元素执行另一个操作。
如果只是一个函数调用,我会说只写两次。它不会终结世界。如果涉及更多,您可以使用装饰器通过通用操作来包装“第一个”函数和“其余”函数。
输出:
或者你可以做一个切片:
How about using
iter
, and consuming the first element?Edit: Going back on the OP's question, there is a common operation that you want to perform on all elements, and then one operation you want to perform on the first element, and another on the rest.
If it's just a single function call, I'd say just write it twice. It won't end the world. If it's more involved, you can use a decorator to wrap your "first" function and "rest" function with a common operation.
Output:
or you could do a slice:
你不能在循环之前执行 root.copy(something.get()) 吗?
编辑:抱歉,我错过了第二部分。但你已经了解了总体思路。否则,枚举并检查
0
?编辑2:好的,摆脱了愚蠢的第二个想法。
Can't you do
root.copy(something.get())
before the loop?EDIT: Sorry, I missed the second bit. But you get the general idea. Otherwise, enumerate and check for
0
?EDIT2: Ok, got rid of the silly second idea.
我不懂 Python,但我使用的模式几乎与您的示例完全相同。
我所做的还使
if
条件成为最常见的条件,因此通常检查if(first == false )
为什么?对于长循环,first 只会有一次为 true,而其他所有时间都为 false,这意味着在除第一个循环之外的所有循环中,程序将检查条件并跳转到 else 部分。
通过检查第一个是否为假,将只有一次跳转到其他部分。我真的不知道这是否会提高效率,但我还是这么做了,只是为了与我内心的书呆子和平相处。
PS:是的,我知道当进入if部分时,它也必须跳过else才能继续执行,所以可能我的做法没什么用,但感觉很好。 :D
I don't know Python, but I use almost the exact pattern of your example.
What I do also is making the
if
condition the most frequent, so usually check forif( first == false )
Why? for long loops, first will be true only one time and will be false all the other times, meaning that in all loops but the first, the program will check for the condition and jump to the else part.
By checking for first being false, there will be only one jump to the else part. I don't really know if this adds efficiency at all, but I do it anyway, just to be in peace with my inner nerd.
PS: Yes, I know that when entering the if part, it also has to jump over the else to continue execution, so probably my way of doing it is useless, but it feels nice. :D
你的问题很矛盾。你说“只在第一次迭代中做一些事情”,而实际上你是说在第一次/后续迭代中做一些不同的事情。这就是我尝试的方式:
Your question is contradictory. You say "only do something on first iteration", when in fact you are saying do something different on first/subsequent iterations. This is how I would attempt it:
这对我有用
Here is what works for me
使用仅针对第一个成员运行的帮助程序,然后适当地替换自身:(
如果您的循环位于函数内部,请将
global
替换为nonlocal
。)With a helper that only runs for the first member and then replaces itself appropriately:
(If your loop is inside a function, replace
global
withnonlocal
.)