2016-07-25 11 views
0

で2クラス要素の比較:だから基本的に私は、次のように2つのリストを持っているは、私は以下に定義されたクラスを持っているのPython

CourseA = [] 
CourseB = [] 

// Extract (multiple) first_name, last_name, age from a file 
CourseA.append(Members(first_name, last_name, age)) # called multiple times 

// Extract (multiple) first_name, last_name, age from a file 
CourseB.append(Members(first_name, last_name, age)) # called multiple times 

class Members(object): 
    def __init__(self, first_name, last_name, age): 
     self.first_name = first_name 
     self.last_name = last_name 
     self.age = age 

私は、そのクラスのインスタンスを含む2つのリストを作成しました:

# CourseA 
John, Smith, 12 
Jane, Doe, 14 
Susan, Patton, 13 

# CourseB 
Richard, Lane, 12 
Susan, Patton, 13 

は、今私はのfirst_namelast_nameを比較したいですおよびCourseB。両方が同じ場合は、対応する年齢を印刷します。この場合、 "Susan Patton"は両方のリストの共通名なので、 "13"を印刷します。

これを行う最も効率的な方法は何ですか?どちらのリストも巨大で、CourseAの名前とCourseBのすべての名前を比較して、CourseAの次の名前とCourseBのすべての名前を比較すると考えましたが、これは非常に遅い方法のようです。

ETA:これでクラス定義に次のコードを追加しました。

def __hash__(self): 
    return hash((self.first_name, self.last_name)) 

def __eq__(self): 
    try: 
     return (self.first_name, self.last_name) == (other.first_name, other.last_name) 
    except AttributeError: 
     return False 

次に、次のように比較します。ところで、私のクラス定義には__eq____hash__がなくても以下の比較のように思えます。

CourseA_set = set((x.first_name, x.last_name) for x in CourseA) 
CourseB_set = set((y.first_name, y.last_name) for y in CourseB) 

for (caller, callee) in CourseA_set.intersection(CourseB_set): 
    print ("Found: {0}".format((caller, callee))) 

私はCourseACourseBの両方で発見されfirst_namelast_nameを得ますか。しかし、他の対応する属性をCourseACourseBから得るにはどうすればいいですか?age

CourseACourseBリストを検索して対応する年齢を取得するには、(first_name, last_name)のリストを検索する必要がありますか?これは非効率的なようだ。

+1

'__eq__'と' __hash__'を実装すると、これを簡単に設定することができます。 – jonrsharpe

+0

年齢の違いにはどうしたらいいですか? – frist

+0

@fristそれは両方の年齢を印刷する必要があります – Rayne

答えて

1

クラスインスタンスをその属性を含むタプルに置き換えます。あなたが代わりに彼らはリストにあるように、そのクラスオフすでにfirst_nameが一致するインスタンスのみを確保する実装

CourseA_set = set(CourseA) # no set comprehension 
CourseB_set = set(CourseB) 

for member in CourseA_set.intersection(CourseB_set): 
    print ("Found: {f} {l} {a}".format(f=member.first_name, 
             l=member.last_name, 
             a=member.age)) 

__hash____eq__方法を属性を除去することなく、セットにリストを回しインスタンスを維持する必要がありますし、両方のセットからのlast_nameは、交差を行った後に保持されます。

+0

これは3つの属性すべてと一致しませんか?私は実際には 'first_name'と' last_name'だけをマッチさせようとしていて、そのマッチに対応する両方のリストから 'age'の値を表示します。 – Rayne

+0

いいえ、それはできません。あなたの '__hash__'と' __eq__'は 'first_name'と' last_name'に実装されていますので、 'age'は考慮されません –

+0

ありがとう!私はすべての属性をこのようにします。しかし、それは 'CourseB'だけから属性を得るようです。 'AgeA'は違うかもしれないので、' CourseA'の属性も同様にどうやって印刷できますか? – Rayne

関連する問題