"For"루프 첫 번째 반복
첫 번째 루프 반복에서 일부 기능을 실행하는 우아한 비단뱀 방식이 있는지 문의하고 싶습니다. 내가 생각할 수있는 유일한 가능성은 다음과 같습니다.
first = True
for member in something.get():
if first:
root.copy(member)
first = False
else:
somewhereElse.copy(member)
foo(member)
Head-Tail 디자인 패턴에 대한 몇 가지 선택 사항이 있습니다.
seq= something.get()
root.copy( seq[0] )
foo( seq[0] )
for member in seq[1:]:
somewhereElse.copy(member)
foo( member )
아니면 이거
seq_iter= iter( something.get() )
head = seq_iter.next()
root.copy( head )
foo( head )
for member in seq_iter:
somewhereElse.copy( member )
foo( member )
사람들은 "중복 된 foo (멤버)"코드 때문에 이것이 "DRY"가 아니라고 우는 소리를냅니다. 말도 안되는 주장입니다. 그것이 사실이라면 모든 기능은 한 번만 사용할 수 있습니다. 참조를 하나만 가질 수 있다면 함수를 정의하는 이유는 무엇입니까?
이와 같은 것이 작동합니다.
for i, member in enumerate(something.get()):
if i == 0:
# Do thing
# Code for everything
그러나 "더러운"작업이기 때문에 실제로 이런 식으로 수행해야하는지 확인하기 위해 코드에 대해 생각하는 것이 좋습니다. 특별한 처리가 필요한 요소를 먼저 가져온 다음 루프의 다른 모든 항목에 대해 정기적으로 처리하는 것이 더 좋습니다.
이런 식으로하지 않는 유일한 이유는 생성기 표현식 (메모리에 맞지 않기 때문에 미리 가져 오기를 원하지 않을 것임)에서 얻을 수있는 큰 목록 또는 유사한 상황 때문입니다. .
어때 :
my_array = something.get()
for member in my_array:
if my_array.index(member) == 0:
root.copy(member)
else:
somewhereElse.copy(member)
foo(member)
또는 아마도 :
for index, member in enumerate(something.get()):
if index == 0:
root.copy(member)
else:
somewhereElse.copy(member)
foo(member)
index-method 문서 .
나는 이것이 매우 우아하다고 생각하지만 그것이하는 일에 너무 복잡 할 수 있습니다 ...
from itertools import chain, repeat, izip
for place, member in izip(chain([root], repeat(somewhereElse)), something.get()):
place.copy(member)
foo(member)
이것은 작동합니다 :
for number, member in enumerate(something.get()):
if not number:
root.copy(member)
else:
somewhereElse.copy(member)
foo(member)
하지만 대부분의 경우 whatever[1:]
루프 외부에서 루트 작업을 반복 하고 수행하는 것이 좋습니다 . 일반적으로 더 읽기 쉽습니다. 물론 사용 사례에 따라 다릅니다.
여기에서 "pertty"로 보일 수있는 Pythonic 관용구를 사용할 수 있습니다. 비록 덜 우아하지만 코드가 더 명확하게 유지되도록 질문을 할 때 제안한 양식을 사용할 가능성이 큽니다.
def copy_iter():
yield root.copy
while True:
yield somewhereElse.copy
for member, copy in zip(something.get(), copy_iter()):
copy(member)
foo(member)
(죄송합니다-편집하기 전에 처음 게시 한 양식이 작동하지 않았으며 실제로 '복사'개체에 대한 반복자를 얻는 것을 잊었습니다)
something.get ()이 무언가를 반복하면 다음과 같이 할 수도 있습니다.
root.copy(something.get())
for member in something.get():
# the rest of the loop
첫 번째 S.Lott 솔루션이 최고라고 생각합니다.하지만 최신 파이썬 (> = 2.6)을 사용하는 경우 다른 선택이 있습니다. 첫 번째 요소와 연속 요소이며, 첫 번째, 두 번째, 세 번째 요소에 대해 별도의 작업을 수행하도록 쉽게 수정할 수 있습니다.
from itertools import izip_longest
seq = [1, 2, 3, 4, 5]
def headfunc(value):
# do something
print "1st value: %s" % value
def tailfunc(value):
# do something else
print "this is another value: %s" % value
def foo(value):
print "perform this at ANY iteration."
for member, func in izip_longest(seq, [headfunc], fillvalue=tailfunc):
func(member)
foo(member)
을 사용 iter
하고 첫 번째 요소를 소비하는 것은 어떻습니까?
편집 : OP의 질문으로 돌아 가면 모든 요소에 대해 수행하려는 공통 작업이 있고 첫 번째 요소에 대해 수행하려는 작업이 있고 나머지 작업이 다른 작업이 있습니다.
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.
def common(item):
print "common (x**2):", item**2
def wrap_common(func):
"""Wraps `func` with a common operation"""
def wrapped(item):
func(item)
common(item)
return wrapped
@wrap_common
def first(item):
"""Performed on first item"""
print "first:", item+2
@wrap_common
def rest(item):
"""Performed on rest of items"""
print "rest:", item+5
items = iter(range(5))
first(items.next())
for item in items:
rest(item)
Output:
first: 2
common (x**2): 0
rest: 6
common (x**2): 1
rest: 7
common (x**2): 4
rest: 8
common (x**2): 9
rest: 9
common (x**2): 16
or you could do a slice:
first(items[0])
for item in items[1:]:
rest(item)
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.
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 for if( 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:
copyfn = root.copy
for member in something.get():
copyfn(member)
foo(member)
copyfn = somewhereElse.copy
참고URL : https://stackoverflow.com/questions/1927544/for-loop-first-iteration
'programing tip' 카테고리의 다른 글
Eclipse 서버 시작 시간 초과를 어떻게 비활성화 할 수 있습니까? (0) | 2020.11.27 |
---|---|
읽기 전용 종속성 속성을 어떻게 생성합니까? (0) | 2020.11.27 |
PHP에서 정수 (intcmp)에 해당하는 strcmp (0) | 2020.11.27 |
mysql로드 데이터 infile이 파일 Errcode : 2의 상태를 가져올 수 없습니다. (0) | 2020.11.27 |
선호 속성 android : dependency의 반대를 수행하는 방법은 무엇입니까? (0) | 2020.11.27 |