2016-12-08 1 views
2

Durch die Programmierung Collective Intelligence von Toby Segaran, dieser Teil des Codes verwirrt mich leicht. In python2 geschrieben, geben die SQLite-Select-Anweisungen einen Iterator zurück, den er dann in einer for-Schleife in (urlid) und später (linker) wiederfindet. Ich verstehe nicht, warum er diese Syntax verwendet, ist das ein Tupel? Und was ist der Zweck? Danke vielmals.Tuple und Iteratoren in For Loops Python

for i in range(iterations): 
    print "Iteration %d" % (i) 
    for (urlid,) in self.con.execute('select rowid from urllist'): 
    pr=0.15 
    # Loop through all the pages that link to this one 
    for (linker,) in self.con.execute(
    'select distinct fromid from link where toid=%d' % urlid): 
     # Get the PageRank of the linker 
     linkingpr=self.con.execute(
     'select score from pagerank where urlid=%d' % linker).fetchone()[0] 

Antwort

2

self.con.execute('select rowid from urllist') gibt eine Liste (oder Tupel) von 1 Elemente bei jeder Iteration.

Diese Syntax:

for (urlid,) in self.con.execute('select rowid from urllist'): 

ist ein schneller Weg zum auszupacken den Skalarwert urlid aus einer eingehenden Tupel/Liste enthält ein Element.

Das zusätzliche Komma am Ende wird verwendet, um die Tupelsyntax von einfachen Klammern zu unterscheiden, die zum Schutz vor Operatoren Vorrang verwendet werden.

Ohne diese Syntax, würden wir zu tun haben:

for urlid_list in self.con.execute('select rowid from urllist'): 
    urlid = urlid_list[0] 

in einem list Auspacken diesem Fall nicht nötig Komma würde auch funktionieren,:

for [urlid] in self.con.execute('select rowid from urllist'): 
+0

Wenn sie mit einzelnen Element Tupeln tun haben, ist es wichtig, das Komma zu erinnern. Ohne sie haben Sie '(urlid)', das nur Klammern verwendet, um einen Ausdruck zu umbrechen, so dass Sie nur "urlid" erhalten, während '(urlid,)' ein Ein-Element-Tupel ist. –

+0

Ja genau, daher der letzte Satz meines Posts. –

1

Diese sehr ungewöhnliche Syntax ist, aber es ist gültig.

Die Sache zu verstehen ist, dass die SQL-Anweisung ausführen immer ein Tupel pro Zeile zurückgibt, auch wenn - wie hier - gibt es nur eine Spalte in diesem Ergebnis. Das Ergebnis sieht also ungefähr so ​​aus:

[(1,), (2,), (3,), (4,)] 

Dies ist eine Liste von Tupeln mit einem einzelnen Element.

Was der Code tut wird jedes Tupel Auspacken so dass urlid und linker sowohl dem einzelnen Element beziehen innerhalb jedes Tupel.

0

Es scheint, dass self.con.execute eine iterierbare Tupel mit einem Element zurückgibt. Die for-Schleife im Beispiel durchläuft jedes Tupel und entpackt das einzelne Elementtupel in eine Variable.

Versuchen Sie in der nächsten Zeile for (urlid,) in self.con.execute durch for urlid in self.con.execute und print (type (urlid)) zu ersetzen. Dies sollte tuple geben, wo das Original den Typ des Elements darin drucken wird.

Sie können auch versuchen, diese zu zeigen, zu helfen, was los ist:

letters = [('a',), ('b',), ('c',)] 

for (letter,) in letters: 
    print(letter) 

for letter_tuple in letters: 
    print(letter_tuple)