Frage

He're ein interessantes Problem, das für die meisten Pythonic Lösung aussieht. Angenommen, ich eine Liste der Zuordnungen {'id': id, 'url': url} haben. Einige ids in der Liste enthalten sind doppelte, und ich möchte eine neue Liste erstellen, wobei alle Duplikate entfernt. Ich kam mit der folgenden Funktion auf:

def unique_mapping(map):
    d = {}
    for res in map:
        d[res['id']] = res['url']

    return [{'id': id, 'url': d[id]} for id in d]

Ich nehme an, es ist sehr effizient. Aber gibt es eine „mehr Pythonic“ Art und Weise? Oder vielleicht eine effizientere Art und Weise?

War es hilfreich?

Lösung

kann Ihr Beispiel etwas neu geschrieben werden, um das erste Wörterbuch zu konstruieren, einen Generator unter Verwendung des Ausdrucks und die Notwendigkeit des Bau von weiteren Zuordnungen zu entfernen. Wiederverwendung nur die alten:

def unique_mapping(mappings):
    return dict((m['id'], m) for m in mappings).values()

Obwohl dies herauskam als Einzeiler, ich denke immer noch, es ist gut lesbar.

Es gibt zwei Dinge, die Sie im Auge zu behalten, wenn Ihre ursprüngliche Lösung und Mine mit:

  • Einzelteile werden nicht immer in der gleichen Reihenfolge zurückgegeben werden, sie waren ursprünglich
  • wird der spätere Eintrag überschrieben vorherigen Einträge mit derselben ID

Wenn Sie nichts dagegen haben, dann schlage ich vor, die Lösung oben. In einem anderen Fall diese Funktion bewahrt Ordnung und behandelt zuerst angetroffene ids mit Priorität:

def unique_mapping(mappings):
    addedIds = set()
    for m in mappings:
        mId = m['id']
        if mId not in addedIds:
            addedIds.add(mId)
            yield m

Unter Umständen müssen Sie es mit list(unique_mappings(mappings)) anrufen, wenn Sie eine Liste und keinen Generator benötigen.

Andere Tipps

Es gibt ein paar Dinge, die man verbessern könnte.

  • Sie ausführen zwei Schleifen, eine über den ursprünglichen dict, und dann wieder über das Ergebnis dict. Sie können Ihre Ergebnisse in einem Schritt statt aufzubauen.

  • Sie könnte sich ändern, einen Generator zu verwenden, up-front die ganze Liste zu vermeiden, zu konstruieren. (Verwenden Liste (unique_mapping (Titel)) auf eine vollständige Liste zu konvertieren, wenn Sie es brauchen)

  • Es gibt keine Notwendigkeit, den Wert zu speichern, wenn nur für Duplikatsprüfung, können Sie ein Set statt.

  • Sie sind neu zu erstellen ein Wörterbuch für jedes Element, anstatt das Original zurück. Dies kann tatsächlich benötigt werden (zB. Sie modifizieren sie, und wollen nicht das Original berühren), aber wenn nicht, sein effizient die Wörterbücher verwenden bereits erstellt.

Hier ist eine Implementierung:

def unique_mapping(items):
    s = set()
    for res in items:
        if res['id'] not in s:
            yield res
            s.add(res['id'])

denke, ich kann dies einfacher noch gemacht werden. Wörterbücher tolerieren keine doppelten Schlüssel. Machen Sie Ihre Liste der Zuordnungen in ein Wörterbuch von Zuordnungen. Dies wird Duplikate entfernen.

>>> 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'}]
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top