2010-07-24 5 views
3

가정하자 나는 다음 개체가 :파이썬 목록 조회 오브젝트 이름, 효율성 조언

class Foo(object): 
    def __init__(self, name=None): 
    self.name = name 

    def __repr__(self): 
    return self.name 

과 같은 여러 인스턴스를 포함하는 목록을 : 나는 객체를 찾으려면

list = [Foo(name='alice'), Foo(name='bob'), Foo(name='charlie')] 

주어진 이름으로 다음을 사용할 수 있습니다 :

def get_by_name(name, list): 
    return [foo for foo in list if foo.name == name][-1] 

분명히 :

print get_by_name('alice', list) 
>> alice 

그러나 더 효율적인 데이터 구조 또는 이러한 개체를 검색하는 방법이 있습니까? 실제로 개체 이름은 런타임에만 알려 지므로 이론적으로 개체의 수명주기 전체에서 변경 될 수 있습니다.

어떤 조언이 필요합니까?

UPDATE :이 방법에

class Foo(object): 
    _all_names = {}  
    def __init__(self, name=None): 
     self._name = None 
     self.name = name   
    @property 
    def name(self): 
     return self._name   
    @name.setter 
    def name(self, name): 
     if self._name is not None: 
      self._all_names[self._name].remove(self) 
     self._name = name 
     if name is not None: 
      self._all_names.setdefault(name, []).append(self) 
    @classmethod 
    def get_by_name(cls, name): 
     return cls._all_names[name]   
    def __repr__(self): 
     return "{0}".format(self.name) 

l = [Foo("alice"), Foo("bob"), Foo('alice'), Foo('charlie')] 
print Foo.get_by_name("alice") 
print Foo.get_by_name("charlie") 

모든 의견을 : 매트 참가자의 대답

덕분에, 나는 그것이 같은 이름을 가진 여러 의를 지원하도록 업데이트했다?

+0

주어진 이름의 개체 또는 * Foo *? –

+0

질문이 업데이트되었습니다. – epoch

+0

당신이 지금 생각하는 것을보십시오. –

답변

8

크기에 대해이 작업을 시도해보십시오

class Foo(object): 
    _all_names = {} 
    def __init__(self, name=None): 
     self.name = name 
    @property 
    def name(self): 
     return self._name 
    @name.setter 
    def name(self, name): 
     self._name = name 
     self._all_names[name] = self 
    @classmethod 
    def get_by_name(cls, name): 
     return cls._all_names[name] 
    def __str__(self): 
     return "Foo({0})".format(self.name) 

a = Foo("alice") 
b = Foo("bob") 
print Foo.get_by_name("alice") 

당신이 여기 저기에 수 많은 개조하면 되겠 어 및 검사가,이 아이디어를 전달하기 위해 최소한의 유지의 마음하십시오.

+0

좋은 아이디어. 델타 self._all_names [self._name]'을 설정자 –

+0

@ THC4k에 추가해야한다 : 나는 그것을 고려했다. 그러나 예외를 피하기 위해'hasattr'와 키 체크가 필요할 것이고, 예제는 시작하기에 충분하다. –

+0

Foo 인스턴스가 삭제 될 때 _all_names를 업데이트하는 가장 좋은 방법은 무엇입니까? – epoch

1

상황이 다소 혼란 스럽습니다.

선형 데이터 구조 인이 개체를 검색 할 것입니다. 뭔가를 찾는 유일한 방법은 하나씩 차례로 살펴 보는 것입니다. 이렇게하면 목록의 길이에 따라 선형 적으로 시간이 늘어납니다. 따라서 인 경우 속도 문제가 발생합니다.

속도 향상을 얻으려면 사용자가 원하는 키 (예 : name)로 개체를 직접 인덱싱 할 수있는 일종의 해시 체계를 사용하는 것이 좋습니다. 이렇게하면 사전 키 조회와 비슷한 방식으로 객체를 찾을 수 있습니다. 그것은 일정한 시간 작동입니다. 이것은 기본적으로 매트의 대답이하는 것입니다. 그는 목록을 걷는 대신 해시를 사용하여 물건을 볼 수 있도록 "색인"을 클래스 수준의 구조로 유지합니다.