2017-12-15 25 views
0

더 많은 비교를 할 사전에 두 데이터 세트 사이에 유사한 레코드를 찾으려고합니다.전역 변수가 작동하지 않는 경우 Python에서 for 루프 외부의 변수에 액세스합니까?

print 문을 사용하여 일치하는 데이터 세트를 찾았습니다 (최종 if 문이 작동하기 전에 모든 코드가 표시됨). 그러나 어떤 이유로 matchingSet2Record을 설정하지 않습니다. 이로 인해 최종 if 문은 일치하는 항목이 발견 되더라도 항상 실행됩니다. 변수를 전역 변수 범위에 있다고 선언하면 작동하지 않습니다. 이것이 일어나는 원인은 무엇입니까? 첫 번째 mathingSet2Record을 for 루프에서 발견 된 레코드로 설정하려면 어떻게해야합니까?

이 코드에서 유일한 문제는 matchingSet2Record이 발견 된 레코드에 올바르게 설정되어 있어도 최종 if 문에서 비교할 때 값이 None 인 경우입니다. 비교 로직이 제대로 작동하고 있습니다. 답변/코멘트를

def processFile(data): 
    # Go through every Record 
    for set1Record in data["Set1"]: 
     value1 = set1Record["Field1"].strip() 
     matchingSet2Record = None 

     # Find the EnergyIP record with the meter number 
     for set2Record in data["Set2"]: 
      if set2Record["Field2"].strip() == value1: 
       global matchingSet2Record 
       matchingSet2Record = set2Record 

     # If there was no matching Set2 record, report it 
     if matchingSet2Record == None: 
      print "Missing" 

업데이트 코드 (여전히 같은 문제를 전시)

def processFile(data): 
    # Go through every Record 
    for set1Record in data["Set1"]: 
     value1 = set1Record["Field1"].strip() 
     matchingSet2Record = None 

     # Find the EnergyIP record with the meter number 
     for set2Record in data["Set2"]: 
      if set2Record["Field2"].strip() == value1: 
       matchingSet2Record = set2Record 

     # If there was no matching Set2 record, report it 
     if matchingSet2Record == None: 
      print "Missing" 

"데이터"사전의 사전은 다음과 같습니다

나는 다음과 같은 기능을 가지고있다. 코드 부분이 제대로 작동하고 있습니다. matchSet2Record를 for 루프 내에서 인쇄 할 때 해당 레코드를 일치하는 레코드로 설정하면 변수가 제대로 설정되었음을 알 수 있습니다. 그러나 for 루프 외부에서 수행하면 None 값이 표시됩니다. 이것이이 코드로 탐구하는 문제입니다. 문제는 일치하는 레코드를 찾는 코드와 관련이 없습니다.

+0

만약 함수의 특정 지점에서 멈추길 원한다면 그것은'return' 문을위한 것입니다. –

+0

그것이 설명되는 문제는 아닙니다. 최종 for 문에서 액세스 할 수 있도록 첫 번째 for..in 루프에서 발견 된 레코드에 None으로 선언 된 matchingSet2Record의 값을 변경할 수 있기를 원합니다. – Kirkland

+0

당신이 게시 한 코드는'globalSetupRecord'가 global로 선언되기 전에'SyntaxError'를 발생시킵니다. 문제가 무엇인지 그리고 당신의 코드가 무효라는 것을 분명히 이해하지 못하기 때문에 질문을 명확히하십시오. –

답변

1

이것은 최종 답변이 아니지만 댓글을 달기에는 너무 많습니다.

data 실제 문제로 문제를 재현하려고했습니다. 하지만 코드가 실제로 작동합니다. 때문에

  • 또는 정말 일치하지 않는, 하나 data

    • 일부 pecularities있을 필요합니다 (반복자는 이미 "소비"때문에, 반복 가능을 통해 두 번 반복 할 때 예를 들어 나는 이상한 효과를 보았다) Field1과 Field2의 두 문자열 사이에 보이지 않는 차이가 있습니다.

    이 작동합니다 : 당신이 학습 파이썬에 경우

    는 다음과 같이 위의 짧은을 작성할 수 있습니다 :

    def processFile(data): 
        # Go through every Record 
        for set1Record in data["Set1"]: 
         value1 = set1Record["Field1"].strip() 
         matchingSet2Record = None 
    
         # Find the EnergyIP record with the meter number 
         for set2Record in data["Set2"]: 
          if set2Record["Field2"].strip() == value1: 
           matchingSet2Record = set2Record 
    
         # If there was no matching Set2 record, report it 
         if matchingSet2Record == None: 
          print("Missing") 
         else: 
          print("Found") 
    
    if __name__ == '__main__': 
        data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1')]) 
        processFile(data) 
    

    Found

    편집를 인쇄

    data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1 ')]) 
    for value1 in [v['Field1'].strip() for v in data['Set1']]: 
        try: 
         matchingSet2Record = (v for v in data['Set2'] if v['Field2'].strip() == value1).next() 
         print("found {}".format(matchingSet2Record)) 
        except StopIteration: 
         print('Missing') 
    

    마지막 줄은 생성자입니다. (. for . in .)은 생성자를 만들고 next()은 첫 번째 일치 항목을 찾을 때까지 생성합니다. 놓치게된다면 StopIteration 예외가 발생합니다.

    data = dict(Set1=[dict(Field1='value1')], Set2=[dict(Field2='value1')]) 
    field1 = [a['Field1'].strip() for a in data['Set1']] 
    field2 = [a['Field2'].strip() for a in data['Set2']] 
    if not set(field1).isdisjoint(field2): 
        print('there is at least 1 common element between Set1 and Set2') 
    

    isdisjoint 부분에 대한 자세한 내용을 this answer를 참조하십시오 : 당신이 알아 내기에 불과 있다면

    는 또는 대안 경우 당신이 할 수있는 Set1과와 Set2를 사이에 중복이 있습니다.

  • +0

    그래, 나는이 질문에 대한 대답으로 그것을 받아 들였다. (질문을 게시하기 전에 내가 왜 "None"이라는 값을 인쇄하는지 궁금해한다.) 하지만 이제는 value1이 목록을 제대로 반복하지만 중첩 for 루프의 value1은 값을 변경하지 않는 것처럼 보입니다. 이것은 for 문 다음에 if 문 앞에 print 문을 추가하여 결정됩니다. 어떤 아이디어가 이것을 일으킬 수 있습니까? – Kirkland

    +0

    질문을 다시 할 수 있습니까? 중첩 된 (= inner) 루프에서 변수 'value1'의 재 할당은 없지만 외부 루프에서만 – hansaplast

    2

    여기에 global 키워드를 사용하지 마십시오. 실제로 전역 변수가 아닌 로컬 변수 matchingSet2Record을 설정하려고합니다.

    코드는 실제 전역 변수에서 변수의 값을 설정하는 것으로 로컬 변수 matchingSet2Record은 변경되지 않고 그대로 유지됩니다. 이로 인해 matchingSet2Record 값이 None으로 업데이트되지 않았으므로 if 문의 조건이 항상 True으로 계산됩니다.

    +0

    감사합니다. 코드에서 글로벌 문을 제거했지만 여전히 동일한 문제가 있습니다. – Kirkland

    +0

    질문에 새 코드를 추가 할 수 있습니까? – ndmeiri

    +0

    질문을 다시 참조하십시오. – Kirkland