2010-03-29 3 views
4

길이가 같지 않은 중첩 목록과 비교하고 싶습니다. 나는 각 하위 목록의 첫 번째 요소 사이의 일치에만 관심이 있습니다. 일치하는 항목이 있으면 다른 목록에 일치 항목을 추가하여 이후에 탭으로 구분 된 파일로 변환하십시오.Python - 중첩 목록을 비교하고 일치 항목을 새 목록에 추가 하시겠습니까?

x = [['1', 'a', 'b'], ['2', 'c', 'd']] 

y = [['1', 'z', 'x'], ['4', 'z', 'x']] 

match = [] 

def find_match(): 
    for i in x: 
     for j in y: 
      if i[0] == j[0]: 
       match.append(j) 
      return match 

이 반환 :

[['1', 'x'], ['1', 'y'], ['1', 'x'], ['1', 'y'], ['1', 'z', 'x']] 

는 중복을 제거 할 목록을 재 처리하는 것이 좋습니다겠습니까하거나이 간단한 방식으로 수행 할 수 있습니다 여기에 내가 함께 일하고 무엇의 예입니다?

비교를 위해 튜플 및/또는 튜플 튜플을 사용하는 것이 더 낫습니까?

도움을 주시면 대단히 감사하겠습니다.

감사합니다. Seafoid.

+2

어떻게 당신은 위의 출력을 받고 와서? 출력으로 [[ '1', 'z', 'x']] 요소 만 가져옵니다. – naivnomore

답변

6
  • 사용은 중복되지 컬렉션을 얻기 위해 설정합니다.

    • 설정 항목은 해시 가능해야하므로 항목 대신 목록 대신 튜플을 사용해야합니다.
  • 게시 한 코드가 게시 한 출력을 생성하지 않는 것 같습니다. 그 입력으로부터 그 출력을 어떻게 생성해야하는지 전혀 모르겠습니다. 예를 들어, 출력은 'y'이고 입력은 그렇지 않습니다.

  • 나는 당신의 기능이 훨씬 향상 될 수 있다고 생각합니다. 현재 x, ymatch을 모듈 수준으로 정의하고이를 명시 적으로 읽고 변이시킵니다. 이것은 함수를 디자인하는 방식이 아닙니다. 일반적으로 함수는 전역 수준에서 무언가를 변경해서는 안됩니다. 명시 적으로 필요한 모든 것을 전달하고 결과를 반환해야하며 암시 적으로 정보를 받고 외부의 내용을 변경하지 않아야합니다.나는 다음 단계로 그 마지막 변경을 촬영하려면

    x = some list 
    y = some list 
    match = [] 
    def find_match(): 
        for i in x: 
         for j in y: 
          if i[0] == j[0]: 
           match.append(j) 
        return match # This is the only line I changed. I think you meant 
           # your return to be over here? 
    find_match() 
    

    x = some list 
    y = some list 
    
    def find_match(x, y): 
        match = [] 
        for i in x: 
         for j in y: 
          if i[0] == j[0]: 
           match.append(j) 
        return match 
    match = find_match(x, y) 
    
  • 에 바꿀 것

    , 나는 보통 유사한 발전기

    와 패턴

    def f(...): 
        return_value = [] 
        for... 
         return_value.append(foo) 
        return return_value 
    

    교체 위의 함수

    def find_match(x, y): 
        for i in x: 
         for j in y: 
          if i[0] == j[0]: 
           yield j 
    

    이 발전기의 효과를 표현하는 또 다른 방법을 만들 것

    def f(...): 
        for... 
         yield foo 
    

    발전기 표현 (j for i in x for j in y if i[0] == j[0]) 함께.

1
if i[1] == j[1] 

검사 어레이의 요소 동일한가. if i[0] == j[0]을 원합니다.

그렇지 않으면 코드가 매우 읽기 쉽고 반드시 변경되지는 않습니다.

2

내가 제대로 질문을 해석하는 경우 알아,하지만 당신이 잘못된 인덱스를 사용하고있는 것으로 보인다 귀하의 예제를 제공하지 않습니다

변화

if i[0] == j[0]: 
+0

정확합니다! 그 점을 지적 해 주셔서 감사합니다. 나는 그것을 편집하고 출력을 보여 주도록 편집했습니다. –

0

if i[1] == j[1]: 

간단한 표현도 여기에서 작동해야합니다.

list_of_lists = filter(lambda l: l[0][0] == l[1][0], zip(x, y)) 
map(lambda l: l[1], list_of_lists) 
+0

이것은 OP가 원했던 것 같지 않은 전체 하위 목록을 비교합니다. –

+0

또한, 이것이 내가 더 간단하게 부르는 것이 확실하지 않습니다. 익명의 함수를 사용하여 필터/맵보다 목록 내포를 사용하는 것이 더 좋습니다. 예를 들어'subx == suby 인 경우 zy (suby, suby의 suby)에 대한 suby '는 코드와 정확히 같지만'filter'보다 읽기가 훨씬 좋다고 생각합니다. '지도'버전. 제 생각에'[subx [0] == suby [0]]'이 OP의 코드와 더 동등하다면 y에있는 suby에 대해 x에있는 subx에 대한 suby라고 생각합니다. –

+0

@Mike 필자는 목록 작성법도 좋아하지만, 기능적인 접근은 나를 잠시 유혹한다. 실수를 지적 해 주셔서 감사합니다. – pajton

1

세트를 사용하면 훨씬 간단하게이 작업을 수행 할 수 있습니다.

set_x = set([i[0] for i in x]) 
set_y = set([i[0] for i in y]) 
matches = list(set_x & set_y) 
+0

감사합니다. Daniel - 세트 내에서 인덱스를 지정할 수 있는지 몰랐습니다. 세트가리스트의 모든 내용에 대해서만 완전한 일치를 리턴한다고 생각했습니다. –

+0

[세트로 작업하는 것이 좋습니다.] 그러나 주문 결과 및 중복 가능성 (결과의 최종 사용 여부에 따라 중요 할 수도 있고 중요하지 않을 수도 있음)과 관련하여 원래의 프로그램과 결과가 다를 것이라고 강조해야합니다. – mjv

+0

@Seafoid : 색인은 x와 y의 하위 목록에 적용되며 세트에는 적용되지 않습니다. – mjv

관련 문제