2010-02-10 2 views
1

모든 목록 항목 확인하기 위해 지능형리스트에서 오류를 잡을 수 나는 절취해야한다. 루프의 끝 부분에서 모든 오류를 수집하여 어떤 객체가 문제를 일으켰는지 보여주고 동시에 모든 목록 요소를 반복하고 싶습니다.나는 루프에 내가 필터 목록 목록 함축을 가지고

내 솔루션 :이 포스트 (How to delete list elements while cycling the list itself without duplicate it) 목록의 중복을 피하고주기에 더 나은 방법이 있다면 물어에서

errors = [] 
copy = objlist[:] 

for obj in copy: 
    try: 
     if (obj.mycond()): 
      # avoiding to touch the list in the loop directly 
      objlist.remove(obj) 
    except MyException as err: 
     errors = [err] 
if (errors): 
    #do something 

return objlist 

.

커뮤니티는 장소 목록 수정을 피하고 예외 문제를 무시할 경우 적용 할 수있는 목록 내포를 사용합니다.

귀하의 관점에서 볼 때 대체 솔루션이 있습니까? 목록 내포를 사용하여 예외를 관리 할 수 ​​있습니까? 이런 종류의 상황에서 큰 목록 (큰 것을 고려해야 만하는 것)을 사용하면 다른 대안을 찾아야합니까?

답변

9

나는 약간의 auxil iary 기능 : 진단이 정확하고 완전 할 수 있도록이 방법은, 그들 각각에 대응하는 모든 잘못된 개체 errs 특정 예외가 있는지

def f(obj, errs): 
    try: return not obj.mycond() 
    except MyException as err: errs.append((obj, err)) 

errs = [] 
l = [obj for obj in objlist if f(obj, errs)] 
if errs: 
    emiterrorinfo(errs) 

참고; l이 필요하며 가능한 한 계속 사용할 수 있도록 objlist을 그대로 사용하십시오. 목록 복사가 필요하지 않으며 obj의 클래스에 대한 변경도없고 코드의 전체 구조는 매우 간단합니다.

0

목록을 복사하고 요소를 제거하는 대신 빈 목록으로 시작하고 필요에 따라 구성원을 추가하십시오. 이런 식으로 뭔가 :

errors = [] 
newlist = [] 

for obj in objlist: 
    try: 
     if not obj.mycond(): 
      newlist.append(obj) 
    except MyException as err: 
     errors.append(err) 
if (errors): 
    #do something 

return newlist 

구문은 같은 꽤 아니지만, 그것은 불필요한 제거하지 않고 지능형리스트가하는 더 많거나 적은 같은 일을 할 수 있습니다.

목록을 끝내거나 다른 곳에서 요소를 추가하거나 제거하면 항목을 제거 할 때 뒤에 오는 모든 항목을 거쳐 색인에서 하나를 뺀 것이기 때문에 느립니다 단, 인덱스에 추가해야하는 것을 제외하고는 무언가를 추가해야합니다. 그 뒤에 오는 모든 요소의 위치를 ​​업데이트하십시오.

당신은() obj.mycond 호출 OBJ하는 방법을 정의 할뿐만 아니라 예외를 캐치 할 수
+0

목록 항목에 대한 일련의 포인터 ("참조") 인 목록 및 메모리에서 위 또는 아래로 이동해야하는 모든 다음 포인터에 관한 목록에서 삽입 및 삭제를 설명하는 것이 더 명확합니다. "색인"이 단순히 "위치"를 의미하지 않는 한 각 항목에 대해 변경해야하는 "색인"이 없지만 모든 사람이 대답을 읽는 것은 결코 명백하지 않습니다. –

+0

@Peter 필자는 실제로 (가장 가능성있는) 구현 방법보다는 개념적 수준에서 설명하려고 노력했다고 생각합니다. 최적화에 관계없이 OO 관점에서 목록을 구현한다면 구현할 수 있습니다. – Davy8

+0

@ Davy8 : "끝까지 갈 필요가 있습니다."아마도 "필요한 것"을 바꿔야 할 것입니다. OO 관점 구현이'a = b [c]'를 어떻게 처리합니까? 인덱스가'c'와 같은 항목을 찾기 위해'b'리스트를 반복합니다? BTW,'errors = [err]'라고하는 코드에서'errors.append (err)'을 의미하지 않습니까? –

0

class obj: 

    def __init__(self): 
     self.errors = [] 

    def mycond(self): 
     #whatever you have here 

    def errorcatcher(): 
     try: 
      return self.mycond() 
     except MyException as err: 
      self.errors.append(err) 
      return False # or true, depending upon what you want 

l = [obj for obj in objlist if not obj.errorcatcher()] 

errors = [obj.errors for obj in objlist if obj.errors] 

if errors: 
    #do something 
+0

obj.errorcatcher()가 아니라면 obj에 obj를 써야 할 것 같습니까? – gahooa

+0

감사합니다 gahooa, 지금 고정 – pwdyson

1

코멘트 몇 : 모든

첫째, 지능형리스트 구문 [expression for var in iterable] 작성 않습니다 사본. 목록의 사본을 작성하지 않으려면 발전기 표현 (expression for var in iterable)을 사용하십시오.

발전기는 어떻게 작동합니까? 기본적으로 GeneratorExit 예외가 발생할 때까지 개체에서 반복적으로 next(obj)을 호출합니다.

원래 코드를 기반으로 필터링 된 목록을 출력물로 필요로하는 것으로 보입니다.

그래서 당신은 약간의 성능 손실이를 에뮬레이션 할 수 있습니다 :

l = [] 
for obj in objlist: 
    try: 
     if not obj.mycond() 
     l.append(obj) 
    except Exception: 
     pass 

을하지만 다시 엔지니어 수있는 발전기 기능을 가진 모든 것을 :

def FilterObj(objlist): 
    for obj in objlist: 
     try: 
     if not obj.mycond() 
      yield obj 
     except Exception: 
     pass 

그런 식으로, 당신은 안전하게 반복 할 수 그 동안 목록을 캐싱하지 않고서는 :

for obj in FilterObj(objlist): 
    obj.whatever()