Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #17472 > unrolled thread
| Started by | HoneyMonster <someone@someplace.invalid> |
|---|---|
| First post | 2011-12-18 19:41 +0000 |
| Last post | 2011-12-20 00:59 +0000 |
| Articles | 15 — 8 participants |
Back to article view | Back to comp.lang.python
Newbie Question: Obtain element from list of tuples HoneyMonster <someone@someplace.invalid> - 2011-12-18 19:41 +0000
Re: Newbie Question: Obtain element from list of tuples Arnaud Delobelle <arnodel@gmail.com> - 2011-12-18 19:49 +0000
Re: Newbie Question: Obtain element from list of tuples Roy Smith <roy@panix.com> - 2011-12-18 15:04 -0500
Re: Newbie Question: Obtain element from list of tuples HoneyMonster <someone@someplace.invalid> - 2011-12-18 20:22 +0000
Re: Newbie Question: Obtain element from list of tuples Roy Smith <roy@panix.com> - 2011-12-18 15:25 -0500
Re: Newbie Question: Obtain element from list of tuples alex23 <wuwei23@gmail.com> - 2011-12-18 18:35 -0800
Re: Newbie Question: Obtain element from list of tuples Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-12-19 03:00 +0000
Re: Newbie Question: Obtain element from list of tuples "Frank Millman" <frank@chagford.com> - 2011-12-19 08:46 +0200
Re: Newbie Question: Obtain element from list of tuples DevPlayer <devplayer@gmail.com> - 2011-12-19 07:37 -0800
Re: Newbie Question: Obtain element from list of tuples alex23 <wuwei23@gmail.com> - 2011-12-19 19:53 -0800
Re: Newbie Question: Obtain element from list of tuples Chris Angelico <rosuav@gmail.com> - 2011-12-19 07:51 +1100
Re: Newbie Question: Obtain element from list of tuples Roy Smith <roy@panix.com> - 2011-12-18 16:10 -0500
Re: Newbie Question: Obtain element from list of tuples HoneyMonster <someone@someplace.invalid> - 2011-12-18 22:55 +0000
Re: Newbie Question: Obtain element from list of tuples Chris Angelico <rosuav@gmail.com> - 2011-12-19 10:40 +1100
Re: Newbie Question: Obtain element from list of tuples HoneyMonster <someone@someplace.invalid> - 2011-12-20 00:59 +0000
| From | HoneyMonster <someone@someplace.invalid> |
|---|---|
| Date | 2011-12-18 19:41 +0000 |
| Subject | Newbie Question: Obtain element from list of tuples |
| Message-ID | <jclflh$u45$1@news.albasani.net> |
Hi, I'm just starting to learn Python, so please bear with me. I have in my program an object (recs) which is a list of tuples (returned as such by a database query). My question is doubtless a very easy one to answer: Say I want the ninth element in the twentieth tuple put into variable PID, I can do this, bearing in mind that numbering starts at zero: tup = recs[19] PID = tup[8] But there must be an easier way; i.e. to do it in one go without the extra variable. How do I achieve that please? Secondly, I am more than happy to read the fine manuals. If someone could point me in the direction of one or two "for idiots" guides, that would be greatly appreciated.
[toc] | [next] | [standalone]
| From | Arnaud Delobelle <arnodel@gmail.com> |
|---|---|
| Date | 2011-12-18 19:49 +0000 |
| Message-ID | <mailman.3804.1324237776.27778.python-list@python.org> |
| In reply to | #17472 |
On 18 December 2011 19:41, HoneyMonster <someone@someplace.invalid> wrote: > Hi, > > I'm just starting to learn Python, so please bear with me. I have in my > program an object (recs) which is a list of tuples (returned as such by a > database query). > > My question is doubtless a very easy one to answer: Say I want the ninth > element in the twentieth tuple put into variable PID, I can do this, > bearing in mind that numbering starts at zero: > > tup = recs[19] > PID = tup[8] > > But there must be an easier way; i.e. to do it in one go without the > extra variable. How do I achieve that please? Well, you were almost there: pid = recs[19][8] Note: all caps is usually reserved for constants in Python. -- Arnaud
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-12-18 15:04 -0500 |
| Message-ID | <roy-B739A1.15041318122011@news.panix.com> |
| In reply to | #17472 |
In article <jclflh$u45$1@news.albasani.net>, HoneyMonster <someone@someplace.invalid> wrote: > Hi, > > I'm just starting to learn Python, so please bear with me. I have in my > program an object (recs) which is a list of tuples (returned as such by a > database query). Sounds like a standard database interface -- each tuple represents one row in the query result. Very common. > My question is doubtless a very easy one to answer: Say I want the ninth > element in the twentieth tuple put into variable PID, I can do this, > bearing in mind that numbering starts at zero: > > tup = recs[19] > PID = tup[8] Sure, you could do: PID = recs[19][8] That's shorter, but it probably not better. Presumably, the tuple elements represent columns in the database. It would make the code easier to read if you unpacked the tuple into something with human-readable names: col_1, col_2, col_3, ...... col_n = recs[19] and then use the name for the column of interest. A common convention is that when you're unpacking a tuple (or a list, I suppose) and are only interested in some of the elements, you unpack the others into "_". Thus: _, _, _, _, pid, _, _, _ = recs[19] Of course, if you're going to do all that, you probably could have written a better query which returned just the column you were interested in. Instead of "select * from foo", you could have done "select pid from foo" (assuming you're using some SQL-based database). > Secondly, I am more than happy to read the fine manuals. If someone could > point me in the direction of one or two "for idiots" guides, that would > be greatly appreciated. The on-line tutorial is pretty good. http://docs.python.org/tutorial/index.html
[toc] | [prev] | [next] | [standalone]
| From | HoneyMonster <someone@someplace.invalid> |
|---|---|
| Date | 2011-12-18 20:22 +0000 |
| Message-ID | <jcli1s$6r3$1@news.albasani.net> |
| In reply to | #17476 |
On Sun, 18 Dec 2011 15:04:13 -0500, Roy Smith wrote: > In article <jclflh$u45$1@news.albasani.net>, > HoneyMonster <someone@someplace.invalid> wrote: > >> Hi, >> >> I'm just starting to learn Python, so please bear with me. I have in my >> program an object (recs) which is a list of tuples (returned as such by >> a database query). > > Sounds like a standard database interface -- each tuple represents one > row in the query result. Very common. > >> My question is doubtless a very easy one to answer: Say I want the >> ninth element in the twentieth tuple put into variable PID, I can do >> this, bearing in mind that numbering starts at zero: >> >> tup = recs[19] >> PID = tup[8] > > Sure, you could do: > > PID = recs[19][8] > > That's shorter, but it probably not better. Presumably, the tuple > elements represent columns in the database. It would make the code > easier to read if you unpacked the tuple into something with > human-readable names: > > col_1, col_2, col_3, ...... col_n = recs[19] > > and then use the name for the column of interest. A common convention > is that when you're unpacking a tuple (or a list, I suppose) and are > only interested in some of the elements, you unpack the others into "_". > Thus: > > _, _, _, _, pid, _, _, _ = recs[19] > > Of course, if you're going to do all that, you probably could have > written a better query which returned just the column you were > interested in. Instead of "select * from foo", you could have done > "select pid from foo" (assuming you're using some SQL-based database). > >> Secondly, I am more than happy to read the fine manuals. If someone >> could point me in the direction of one or two "for idiots" guides, that >> would be greatly appreciated. > > The on-line tutorial is pretty good. > http://docs.python.org/tutorial/index.html Thanks, Arnaud and Roy. I had no idea it could be so easy. I think I rather like Python! OK, I'll change PID to pid if that's best practice. Yes, it's an SQL-based database, PostgreSQL actually. I'm using psycopg2 to access it and wxGlade to construct the GUI interface. It all seems to be progressing very smoothly. Thanks again.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-12-18 15:25 -0500 |
| Message-ID | <roy-69CF7D.15250618122011@news.panix.com> |
| In reply to | #17478 |
In article <jcli1s$6r3$1@news.albasani.net>, HoneyMonster <someone@someplace.invalid> wrote: > I think I rather like Python! +1 QOTD?
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2011-12-18 18:35 -0800 |
| Message-ID | <2c286dea-efba-45d5-85a7-a7503733575a@i6g2000vbe.googlegroups.com> |
| In reply to | #17476 |
Roy Smith <r...@panix.com> wrote:
> A common convention
> is that when you're unpacking a tuple (or a list, I suppose) and are
> only interested in some of the elements, you unpack the others into "_".
> Thus:
>
> _, _, _, _, pid, _, _, _ = recs[19]
Pre-namedtuple, I used to like using named slices for this:
cPID = slice(19)
pid = recs[cPID]
cHostPort = slice(99,100)
host, port = recs[cHostPort]
etc.
The suggestions of having your query return a dictionary where
possible are the most ideal, but if it's not possible you can always
wrap the result tuple in a namedtuple:
from collections import namedtuple
Staff = namedtuple('Staff',
['firstname','lastname','age','position'])
sql_result = ('John', 'Example', '30', 'Dummy')
staff_record = Staff(sql_result)
print staff_record.firstname, staff_record.age
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-12-19 03:00 +0000 |
| Message-ID | <4eeea8eb$0$11091$c3e8da3@news.astraweb.com> |
| In reply to | #17492 |
On Sun, 18 Dec 2011 18:35:47 -0800, alex23 wrote: > Pre-namedtuple, I used to like using named slices for this: > > cPID = slice(19) > pid = recs[cPID] You know, that is an incredibly simple thing and yet it never dawned on me before now. Thank you for sharing that. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | "Frank Millman" <frank@chagford.com> |
|---|---|
| Date | 2011-12-19 08:46 +0200 |
| Message-ID | <mailman.3815.1324277206.27778.python-list@python.org> |
| In reply to | #17494 |
"Steven D'Aprano" <steve+comp.lang.python@pearwood.info> wrote in message news:4eeea8eb$0$11091$c3e8da3@news.astraweb.com... > On Sun, 18 Dec 2011 18:35:47 -0800, alex23 wrote: > >> Pre-namedtuple, I used to like using named slices for this: >> >> cPID = slice(19) >> pid = recs[cPID] > > You know, that is an incredibly simple thing and yet it never dawned on > me before now. Thank you for sharing that. > I also like it, but it does not work quite so simply for me. >>> row = tuple(range(20)) >>> cPID = slice(15) >>> pid = row[cPID] >>> pid (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) >>> This works - >>> row = tuple(range(20)) >>> cPID = slice(15, 16) >>> pid, = row[cPID] # note the trailing comma >>> pid 15 >>> Still nice, but not quite so elegant. Am I missing something? Frank Millman
[toc] | [prev] | [next] | [standalone]
| From | DevPlayer <devplayer@gmail.com> |
|---|---|
| Date | 2011-12-19 07:37 -0800 |
| Message-ID | <ebd6cc29-c66e-47be-a028-83c4beb8a277@n6g2000vbz.googlegroups.com> |
| In reply to | #17500 |
On Dec 19, 1:46 am, "Frank Millman" <fr...@chagford.com> wrote: > "Steven D'Aprano" <steve+comp.lang.pyt...@pearwood.info> wrote in message > > news:4eeea8eb$0$11091$c3e8da3@news.astraweb.com... > > > On Sun, 18 Dec 2011 18:35:47 -0800, alex23 wrote: > > >> Pre-namedtuple, I used to like using named slices for this: > > >> cPID = slice(19) > >> pid = recs[cPID] > > > You know, that is an incredibly simple thing and yet it never dawned on > > me before now. Thank you for sharing that. > > I also like it, but it does not work quite so simply for me. > > >>> row = tuple(range(20)) > >>> cPID = slice(15) > >>> pid = row[cPID] > >>> pid > > (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14) > > > > This works - > > > > >>> row = tuple(range(20)) > >>> cPID = slice(15, 16) > >>> pid, = row[cPID] # note the trailing comma > >>> pid > 15 > > Still nice, but not quite so elegant. > > Am I missing something? > > Frank Millman if you're going to do: > >>> cPID = slice(15, 16) > >>> pid, = row[cPID] # note the trailing comma Why not just: >>>row = tuple(range(20)) >>>cPID = 15 # a proposed constant >>>pid = row[cPID] >>>pid 15 It might be better for other's to debug if you use >>> pid, _ = row[cPID] as a little tiny comma like that is easy to miss in some text editors. Not everyone has large LCD screens. Not that I like the "_" for this purpose. Personally I'd love to see the "_" used instead of "self" as a common practice (useful when you use lots of "self...." on a line).
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2011-12-19 19:53 -0800 |
| Message-ID | <0b32499a-5e7d-4fb6-a790-df28bd05d887@s5g2000vbj.googlegroups.com> |
| In reply to | #17500 |
On Dec 19, 4:46 pm, "Frank Millman" <fr...@chagford.com> wrote: > Am I missing something? No, I seem to be. I have _no_ idea how I got that original syntax to work :| My apologies, DevPlayer's suggestion is much more sensible, although slices are still handy when dealing with groups of values.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-12-19 07:51 +1100 |
| Message-ID | <mailman.3807.1324241477.27778.python-list@python.org> |
| In reply to | #17472 |
On Mon, Dec 19, 2011 at 6:41 AM, HoneyMonster <someone@someplace.invalid> wrote:
> My question is doubtless a very easy one to answer: Say I want the ninth
> element in the twentieth tuple put into variable PID, I can do this,
> bearing in mind that numbering starts at zero:
>
> tup = recs[19]
> PID = tup[8]
>
> But there must be an easier way; i.e. to do it in one go without the
> extra variable. How do I achieve that please?
The specific answer has already been given, but I'd like to fill in
the generality. In Python, everything's an object; if you can do
something with a variable, you can do it with an expression too. I
don't know what your function call is to obtain your record list, but
imagine it's:
recs = conn.query("SELECT * FROM some_table")
Then you can actually do all of this in a single statement. It's not
usually what you'll want to do, but this is legal:
pid = conn.query("SELECT * FROM some_table")[19][8]
If you're absolutely certain that you'll always get precisely one
value from a query, this becomes rather more useful:
mode = conn.query("SELECT mode FROM config WHERE id=5")[0][0]
In any case: You can work with a function's return value directly,
without first storing it in a temporary variable.
Hope that helps!
Chris Angelico
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2011-12-18 16:10 -0500 |
| Message-ID | <roy-78470D.16102518122011@news.panix.com> |
| In reply to | #17480 |
In article <mailman.3807.1324241477.27778.python-list@python.org>,
Chris Angelico <rosuav@gmail.com> wrote:
> If you're absolutely certain that you'll always get precisely one
> value from a query, this becomes rather more useful:
>
> mode = conn.query("SELECT mode FROM config WHERE id=5")[0][0]
Although, if you're going to do that, you might as well take advantage
of the fetchone() method that most Python database APIs have and
eliminate one of the indexes. Typical code would be something like:
cursor.execute("SELECT mode FROM config WHERE id=5")
mode = cursor.fetchone()[0]
If you're going to be doing any database work in Python, you should be
familiar with the Python Database API Specification,
http://www.python.org/dev/peps/pep-0249/. Most of the vendor-specific
database modules have interfaces which hold pretty close to the style
described there.
You might also want to explore SQL_Alchemy. I personally find it
difficult and painful to work with, but it does have the powerful
advantage that it abstracts away all the vendor-specific differences
between databases.
[toc] | [prev] | [next] | [standalone]
| From | HoneyMonster <someone@someplace.invalid> |
|---|---|
| Date | 2011-12-18 22:55 +0000 |
| Message-ID | <jclr1a$kjn$2@news.albasani.net> |
| In reply to | #17480 |
On Mon, 19 Dec 2011 07:51:08 +1100, Chris Angelico wrote:
> On Mon, Dec 19, 2011 at 6:41 AM, HoneyMonster
> <someone@someplace.invalid> wrote:
>> My question is doubtless a very easy one to answer: Say I want the
>> ninth element in the twentieth tuple put into variable PID, I can do
>> this, bearing in mind that numbering starts at zero:
>>
>> tup = recs[19]
>> PID = tup[8]
>>
>> But there must be an easier way; i.e. to do it in one go without the
>> extra variable. How do I achieve that please?
>
> The specific answer has already been given, but I'd like to fill in the
> generality. In Python, everything's an object; if you can do something
> with a variable, you can do it with an expression too. I don't know what
> your function call is to obtain your record list, but imagine it's:
>
> recs = conn.query("SELECT * FROM some_table")
>
> Then you can actually do all of this in a single statement. It's not
> usually what you'll want to do, but this is legal:
>
> pid = conn.query("SELECT * FROM some_table")[19][8]
>
> If you're absolutely certain that you'll always get precisely one value
> from a query, this becomes rather more useful:
>
> mode = conn.query("SELECT mode FROM config WHERE id=5")[0][0]
>
> In any case: You can work with a function's return value directly,
> without first storing it in a temporary variable.
>
> Hope that helps!
Thanks, Chris. Actually I had simplified the question somewhat. The
actuality is indeed - as you suspected - that recs = conn.query("SELECT *
FROM some_table") but I am then using the recs object to populate a (non
editable) wxGrid.
When the user selects a row and clicks a button, I am using:
pos = self.grid_1.GetGridCursorRow() to establish which tuple in recs is
involved, and then pid = recs[pos][4] to determine the key value (I
suspected that accessing recs directly would be more efficient that
trying to determine the wxGrid column value, and in any case the pid is
in recs but not in the wxGrid).
I trust this all makes sense. Thanks again.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2011-12-19 10:40 +1100 |
| Message-ID | <mailman.3808.1324251610.27778.python-list@python.org> |
| In reply to | #17482 |
On Mon, Dec 19, 2011 at 9:55 AM, HoneyMonster <someone@someplace.invalid> wrote:
> When the user selects a row and clicks a button, I am using:
> pos = self.grid_1.GetGridCursorRow() to establish which tuple in recs is
> involved, and then pid = recs[pos][4] to determine the key value (I
> suspected that accessing recs directly would be more efficient that
> trying to determine the wxGrid column value, and in any case the pid is
> in recs but not in the wxGrid).
Yep, this looks like a sensible way to do it!
I would recommend, though, that you avoid "magic numbers" - the
process ID might happen to be in cell 4, but what if your column list
changes? This is especially problematic when you use "select * from
table", because changes outside your code can break things.
There's two solutions. One is to carefully match your SELECT statement
to a set of constants:
exec("SELECT FOO,BAR,QUUX,ASDF,PID,WHATEVER FROM table")
FOO,BAR,QUUX,ASDF,PID,WHATEVER,*_=range(20) # Cool trick to avoid
having to count the columns
But a better way is to let the database handle it. Check your
interface library to see if you can have it return dictionaries or
objects instead of tuples - then you could use:
pid = recs[pos]["pid"]
# or
pid = recs[pos]->pid
which avoids the need to count columns at all.
Other than that, though, yep - your code concept looks fine.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | HoneyMonster <someone@someplace.invalid> |
|---|---|
| Date | 2011-12-20 00:59 +0000 |
| Message-ID | <jcomlk$6m9$1@news.albasani.net> |
| In reply to | #17483 |
On Mon, 19 Dec 2011 10:40:06 +1100, Chris Angelico wrote:
> On Mon, Dec 19, 2011 at 9:55 AM, HoneyMonster
> <someone@someplace.invalid> wrote:
>> When the user selects a row and clicks a button, I am using:
>> pos = self.grid_1.GetGridCursorRow() to establish which tuple in recs
>> is involved, and then pid = recs[pos][4] to determine the key value (I
>> suspected that accessing recs directly would be more efficient that
>> trying to determine the wxGrid column value, and in any case the pid is
>> in recs but not in the wxGrid).
>
> Yep, this looks like a sensible way to do it!
>
> I would recommend, though, that you avoid "magic numbers" - the process
> ID might happen to be in cell 4, but what if your column list changes?
> This is especially problematic when you use "select * from table",
> because changes outside your code can break things.
>
> There's two solutions. One is to carefully match your SELECT statement
> to a set of constants:
>
> exec("SELECT FOO,BAR,QUUX,ASDF,PID,WHATEVER FROM table")
> FOO,BAR,QUUX,ASDF,PID,WHATEVER,*_=range(20) # Cool trick to avoid having
> to count the columns
>
> But a better way is to let the database handle it. Check your interface
> library to see if you can have it return dictionaries or objects instead
> of tuples - then you could use:
>
> pid = recs[pos]["pid"]
> # or pid = recs[pos]->pid
>
> which avoids the need to count columns at all.
>
> Other than that, though, yep - your code concept looks fine.
Thanks again, Chris. I'm completely new to Python, but am an old had at
databases. I *never* use "select *" in a production environment; rather
an explicit list of columns. Thus it doesn't matter if a column is added
to the table, nor if the column order in the table is changed.
But I have used this at the start if my code to make it more readable
anyway:
# Define constants (position in tuple)
Title = 0
Episode = 1
Categories = 2
Channel = 3
PID = 4
Index = 5
so that in the bit where I populate the grid, the code is now:
cnt = 0
for tup in recs:
self.grid_1.SetCellValue(cnt, Title, tup[Title])
self.grid_1.SetCellValue(cnt, Episode, tup[Episode])
self.grid_1.SetCellValue(cnt, Categories, tup[Categories])
self.grid_1.SetCellValue(cnt, Channel, tup[Channel])
cnt = cnt + 1
just so that is more legible.
Cheers,
HM
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web