매핑 목록에서 고유 한 항목을 추출합니다
-
06-07-2019 - |
문제
그는 가장 피해자 솔루션을 찾는 흥미로운 문제입니다. 매핑 목록이 있다고 가정 해 봅시다 {'id': id, 'url': url}
. 약간 id
목록의 S는 중복되어 있으며 모든 복제물을 제거한 상태에서 새 목록을 만들고 싶습니다. 다음과 같은 기능을 생각해 냈습니다.
def unique_mapping(map):
d = {}
for res in map:
d[res['id']] = res['url']
return [{'id': id, 'url': d[id]} for id in d]
나는 그것이 매우 효율적이라고 생각합니다. 그러나 "더 많은 피스닉"방법이 있습니까? 아니면 더 효율적인 방법?
해결책
발전기 표현식을 사용하여 첫 번째 사전을 구성하고 다른 매핑의 구성의 필요성을 제거하기 위해 예제를 약간 다시 작성할 수 있습니다. 오래된 것들을 재사용하십시오.
def unique_mapping(mappings):
return dict((m['id'], m) for m in mappings).values()
이것은 하나의 라이너로 나왔지만 여전히 읽을 수 있다고 생각합니다.
원래 솔루션과 광산을 사용할 때 명심해야 할 두 가지가 있습니다.
- 항목이 원래와 같은 순서로 항상 반환되는 것은 아닙니다.
- 이후의 항목은 동일한 ID로 이전 항목을 덮어 씁니다.
마음에 들지 않으면 위의 해결책을 제안합니다. 다른 경우,이 기능은 순서를 보존하고 최초의 ID를 우선 순위로 처리합니다.
def unique_mapping(mappings):
addedIds = set()
for m in mappings:
mId = m['id']
if mId not in addedIds:
addedIds.add(mId)
yield m
당신은 그것을 호출해야 할 수도 있습니다 list(unique_mappings(mappings))
생성기가 아닌 목록이 필요한 경우.
다른 팁
개선 할 수있는 몇 가지가 있습니다.
당신은 원래의 덕트 위에 하나씩 두 개의 루프를 수행 한 다음 다시 결과를 통해 결과를 수행하고 있습니다. 대신 한 단계로 결과를 쌓을 수 있습니다.
전체 목록을 선불로 구성하지 않도록 발전기를 사용하도록 변경할 수 있습니다. (필요한 경우 전체 목록으로 변환하려면 목록을 사용합니다 (고유 한 맵핑 (항목)))
중복을 확인할 때 값을 저장할 필요가 없습니다. 대신 세트를 사용할 수 있습니다.
원본을 반환하지 않고 각 요소에 대한 사전을 재현하고 있습니다. 이것은 실제로 필요할 수 있습니다 (예 : 당신은 그것들을 수정하고 원본을 만지고 싶지 않음), 그렇지 않은 경우 이미 생성 된 사전을 사용하는 것이 더 효율적입니다.
구현은 다음과 같습니다.
def unique_mapping(items):
s = set()
for res in items:
if res['id'] not in s:
yield res
s.add(res['id'])
나는 이것이 여전히 더 간단하게 만들 수 있다고 생각합니다. 사전은 중복 키를 견딜 수 없습니다. 매핑 목록을 매핑 사전으로 만듭니다. 복제물이 제거됩니다.
>>> someListOfDicts= [
{'url': 'http://a', 'id': 'a'},
{'url': 'http://b', 'id': 'b'},
{'url': 'http://c', 'id': 'a'}]
>>> dict( [(x['id'],x) for x in someListOfDicts ] ).values()
[{'url': 'http://c', 'id': 'a'}, {'url': 'http://b', 'id': 'b'}]