2008-10-27 5 views
7

Stellen Sie sich vor, Sie haben eine Entität im Google App Engine-Datenspeicher, in der Links für anonyme Benutzer gespeichert sind. Sie mögen die folgende SQL-Abfrage ausführen, die nicht unterstützt wird:Python: DISTINCT auf GQuery-Ergebnismenge (GQL, GAE)

SELECT DISTINCT user_hash FROM links 

Stattdessen könnten Sie:

user = db.GqlQuery("SELECT user_hash FROM links") 

Wie Python verwenden, am effizientesten das Ergebnis zu filtern, so dass es Gibt eine DISTINCT-Ergebnismenge zurück? Wie wird die DISTINCT-Ergebnismenge gezählt?

Antwort

3

Eine Reihe guter Weg, um das zu lösen ist:,

>>> a = ['google.com', 'livejournal.com', 'livejournal.com', 'google.com', 'stackoverflow.com'] 
>>> b = set(a) 
>>> b 
set(['livejournal.com', 'google.com', 'stackoverflow.com']) 
>>> 

Ein Vorschlag w/r/t die erste Antwort ist, dass Sets und dicts besser sind einzigartige Ergebnisse schnell abrufen, die Mitgliedschaft in Listen ist O (n) im Vergleich zu O (1) für die anderen Typen, also, wenn Sie möchten, um zusätzliche Daten zu speichern, oder etwas tun, wie schaffen die erwähnte unique_results Liste, kann es besser sein, etwas zu tun wie:

unique_results = {} 
>>> for item in a: 
    unique_results[item] = '' 


>>> unique_results 
{'livejournal.com': '', 'google.com': '', 'stackoverflow.com': ''} 
+0

Ein Set-Objekt ist eine ungeordnete Sammlung von verschiedenen hashbaren Objekten. (...) Neu in Version 2.4. http://www.python.org/doc/2.5.2/lib/types-set.html –

+1

Set ist in Ordnung, wenn die Anzahl der Datensätze relativ klein ist. Aber wenn Sie Milliarden von Datensätzen im Datenspeicher haben, wäre das ziemlich ineffizient! Eine viel bessere Strategie wäre es, das Ergebnis vor der Einfüge-/Aktualisierungszeit vorzuberechnen und zu speichern. – sudarkoff

1

Eine Möglichkeit wäre, die Ergebnisse in eine gestellte Aufgabe zu setzen:

http://www.python.org/doc/2.6/library/sets.html#sets.Set

Der resultierende Satz nur der unterschiedlichen Werte bestanden darin bestehen wird.

In diesem Fall würde der Aufbau einer neuen Liste, die nur die eindeutigen Objekte enthält, funktionieren. Etwas wie:

unique_results = [] 
for obj in user: 
    if obj not in unique_results: 
     unique_results.append(obj) 

Die for Schleife kann auch in eine Liste Verständnis kondensiert werden.

0

Sorry graben Sie diese Frage, aber in GAE kann ich solche Objekte nicht vergleichen, ich muss uns e .key() zum Vergleich wie folgt aus:

Vorsicht, das ist sehr ineffizient:

def unique_result(array): 
    urk={} #unique results with key 
    for c in array: 
     if c.key() not in urwk: 
      urk[str(c.key())]=c 
    return urk.values() 

Wenn jemand eine bessere Lösung hat, bitte teilen.

+0

Es gibt eine andere Frage, wie Sie dies in Datastore tun können, und die grundlegende Antwort ist, dass Sie nicht: http://stackoverflow.com/questions/1183102/how-to-get-the-distinct-value-of-one -von-meinen-Modellen-in-google-app-engine. Ich habe versucht, einige vage Ideen zur Denormalisierung vorzuschlagen, aber es ist möglich, dass sich der Stand der Technik seitdem weiterentwickelt hat. –

5

Neubelebung diese Frage für die Fertigstellung:

das Schlüsselwort distinct hat in release 1.7.4 eingeführt.

Sie können die aktualisierte GQL-Referenz (zum Beispiel für Python) here finden.