Reputation: 196
Working through Programming Collective Intelligence by Toby Segaran, this part of code confused me slightly. Written in python2, the sqlite select statements return an iterator which he then retrieves in a for loop into (urlid,) and later (linker,) I don't understand why he uses this syntax, is that a tuple? And what is the purpose? Many thanks.
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]
Upvotes: 2
Views: 108
Reputation: 140168
self.con.execute('select rowid from urllist')
returns a list (or tuple) of 1 element at each iteration.
This syntax:
for (urlid,) in self.con.execute('select rowid from urllist'):
is a quick way to unpack the scalar value urlid
from an incoming tuple/list containing one element.
The extra comma at the end is used to differentiate the tuple syntax from a simple parentheses used to protect from operator precedence.
Without that syntax, we would have to do:
for urlid_list in self.con.execute('select rowid from urllist'):
urlid = urlid_list[0]
Unpacking in a list
would also work, no need for comma in that case:
for [urlid] in self.con.execute('select rowid from urllist'):
Upvotes: 2
Reputation: 16987
It seems that self.con.execute
returns an iterable of tuples with one element. The for loop in the example goes through each tuple and unpacks the single element tuple into one variable.
Try replacing for (urlid,) in self.con.execute
with for urlid in self.con.execute
and print (type (urlid))
in the next line. This should give tuple
, where as the original will print the type of the element inside it.
You can also try this to help show what is going on:
letters = [('a',), ('b',), ('c',)]
for (letter,) in letters:
print(letter)
for letter_tuple in letters:
print(letter_tuple)
Upvotes: 0
Reputation: 599550
This is very unusual syntax, but it is valid.
The thing to understand is that the SQL execute statement will always return a tuple per row, even if - as here - there is only one column in that result. So the result looks something like this:
[(1,), (2,), (3,), (4,)]
which is a list of single-item tuples.
What the code is doing is unpacking each tuple so that urlid
and linker
both refer to the single element within each tuple.
Upvotes: 1