2010-02-02 8 views
3

일부 요소를 더 많은 요소로 확장해야하는 목록을 처리하는 "좋은"방법을 찾고 있습니다 (단 한 번만 결과에 확장이 없음).목록의 요소 확장하기

표준 반복적 인 방법은 어떻게하는 것입니다 :

i=0 
while i < len(l): 
    if needs_expanding(l[i]): 
     new_is = expand(l[i]) 
     l[i:i] = new_is 
     i += len(new_is) 
    else: 
     i += 1 

꽤 추한이다. 다음과 같이 내용을 새 목록으로 다시 쓸 수 있습니다.

nl = [] 
for x in l: 
    if needs_expanding(x): 
     nl += expand(x) 
    else: 
     nl.append(x) 

그러나 둘 다 너무 길게 보입니다. 또는 단순히 2 단계를 수행하고 나중에 목록을 평평하게 할 수 있습니다.

flatten(expand(x) if needs_expanding(x) else x for x in l) 
# or 
def try_expanding(x).... 
flatten(try_expanding(x) for x in l) 

그러나이 경우에도 "올바르게"느껴지지 않습니다.

다른 방법이 있습니까?

+0

두 번째 버전은 충분히 명확하다고 생각합니다. – kennytm

+0

@KennyTM : 나는 보통 마지막 것을 사용합니다. 다른 사람들이 실제 코드를 사용하고/사용하는 것을 편안하게 생각할 수있는 것을보고 싶었습니다. – viraptor

답변

2

당신이 생성하는 목록에 랜덤 액세스가 필요하지 않은 경우, 당신은 또한 사용할 수있는 발전기를 작성합니다.

def iter_new_list(old_list):  
    for x in old_list: 
     if needs_expanding(x): 
      for y in expand(x): 
       yield y 
     else: 
      yield x 

new_list = list(iter_new_list(old_list)) 

이것은 기능적으로 두 번째 예와 동일하지만 실제 상황에서는 더 읽기 쉽습니다.

또한 파이썬 코딩 표준은 숫자 이름과 거의 구별되지 않으므로 소문자 -L을 변수 이름으로 사용하는 것을 금지합니다.

+0

목록의 2 차 성능을가집니다. 소문자 - L - pylint는 계속 상기시켜줍니다;) 나는 사소한 예를 들어 타이핑을 저장하는 데에만 사용했습니다 ... – viraptor

2

마지막 하나는 가장 파이썬 아마,하지만 당신은지도 묵시적 루프 (또는 py3에서, 발전기)을 시도 할 수 :

flatten(map(lambda x: expand(x) if needs_expanding(x) else x, l)) 
flatten(map(try_expanding, l)) 
3

귀하의 마지막 두 답변을 내가 어떻게 할 것인지입니다. 나는 flatten()에 익숙하지 않지만 그런 기능이 있다면 이상적입니다. 또한 내장 sum() 사용할 수 있습니다

sum(expand(x) if needs_expanding(x) else [x] for x in l, []) 
sum(needs_expanding(x) and expand(x) or [x] for x in l, []) 
+0

Ok - sum은 꽤 멋지다 - 저것을 생각하지 않았다. Flatten은 목록을 평평하게하는 몇 가지 커스텀 함수입니다 - 불행히도 Python에서는 아닙니다. – viraptor

+1

불행히도'sum()'은 –