Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #108275 > unrolled thread
| Started by | DFS <nospam@dfs.com> |
|---|---|
| First post | 2016-05-07 12:51 -0400 |
| Last post | 2016-05-08 18:24 -0400 |
| Articles | 20 on this page of 69 — 19 participants |
Back to article view | Back to comp.lang.python
pylint woes DFS <nospam@dfs.com> - 2016-05-07 12:51 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 03:01 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-07 21:16 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 11:36 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-07 22:15 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 12:50 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-10 18:36 -0400
Re: pylint woes MRAB <python@mrabarnett.plus.com> - 2016-05-11 02:02 +0100
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-07 19:14 -0700
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-07 23:04 -0400
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-07 20:46 -0700
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 10:26 -0400
Re: pylint woes Jussi Piitulainen <jussi.piitulainen@helsinki.fi> - 2016-05-08 08:50 +0300
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 10:25 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-09 00:36 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 11:06 -0400
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-08 08:15 -0700
Re: pylint woes Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-05-09 13:17 +1200
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-09 12:18 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 22:58 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-09 01:15 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:06 -0400
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-08 08:11 -0700
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-09 01:51 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:04 -0400
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-09 13:09 +1000
Re: pylint woes MRAB <python@mrabarnett.plus.com> - 2016-05-08 03:21 +0100
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-08 21:36 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:24 -0400
Re: pylint woes Joel Goldstick <joel.goldstick@gmail.com> - 2016-05-08 17:39 -0400
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-09 13:46 +1000
Re: pylint woes Michael Selik <michael.selik@gmail.com> - 2016-05-07 18:42 +0000
Re: pylint woes Peter Pearson <pkpearson@nowhere.invalid> - 2016-05-07 18:43 +0000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:05 -0400
Re: pylint woes Christopher Reimer <christopher_reimer@icloud.com> - 2016-05-07 11:52 -0700
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-07 23:38 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 13:56 +1000
Re: pylint woes Peter Otten <__peter__@web.de> - 2016-05-08 16:19 +0200
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-07 12:21 -0700
Re: pylint woes Stephen Hansen <me@ixokai.io> - 2016-05-07 12:23 -0700
Re: pylint woes Terry Reedy <tjreedy@udel.edu> - 2016-05-07 15:40 -0400
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-07 23:28 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 13:51 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 00:40 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 14:55 +1000
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-07 20:55 -0700
Re: pylint woes Ian Kelly <ian.g.kelly@gmail.com> - 2016-05-07 23:09 -0600
Re: pylint woes Peter Otten <__peter__@web.de> - 2016-05-08 16:12 +0200
Re: pylint woes Christopher Reimer <christopher_reimer@icloud.com> - 2016-05-07 12:43 -0700
Re: pylint woes Ray Cote <rgacote@appropriatesolutions.com> - 2016-05-07 15:52 -0400
Re: pylint woes Christopher Reimer <christopher_reimer@icloud.com> - 2016-05-07 13:20 -0700
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 07:56 +1000
Re: pylint woes Terry Reedy <tjreedy@udel.edu> - 2016-05-07 21:44 -0400
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-08 13:25 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 00:10 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 14:21 +1000
Re: pylint woes "D'Arcy J.M. Cain" <darcy@VybeNetworks.com> - 2016-05-08 08:50 -0400
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-08 23:01 +1000
Re: pylint woes Larry Hudson <orgnut@yahoo.com> - 2016-05-08 13:45 -0700
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-09 08:07 +1000
Re: pylint woes Larry Hudson <orgnut@yahoo.com> - 2016-05-08 18:28 -0700
Re: pylint woes Dan Sommers <dan@tombstonezero.net> - 2016-05-08 20:49 +0000
Re: pylint woes Chris Angelico <rosuav@gmail.com> - 2016-05-09 08:10 +1000
Re: pylint woes Steven D'Aprano <steve@pearwood.info> - 2016-05-09 03:25 +1000
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:16 -0400
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-08 14:38 -0700
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 17:46 -0400
Re: pylint woes Stephen Hansen <me+python@ixokai.io> - 2016-05-08 15:05 -0700
Re: pylint woes DFS <nospam@dfs.com> - 2016-05-08 18:24 -0400
Page 1 of 4 [1] 2 3 4 Next page →
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-07 12:51 -0400 |
| Subject | pylint woes |
| Message-ID | <ngl677$68p$1@dont-email.me> |
This more-anal-than-me program generated almost 2 warnings for every
line of code in my program. w t hey?
DFS comments
+-------------------------+------------+ -------------------------------
|message id |occurrences |
+=========================+============+
|mixed-indentation |186 | I always use tab
+-------------------------+------------+
|invalid-name |82 | every single variable name?!
+-------------------------+------------+
|bad-whitespace |65 | mostly because I line up =
signs:
var1 = value
var10 = value
+-------------------------+------------+
|trailing-whitespace |59 | heh!
+-------------------------+------------+
|multiple-statements |23 | do this to save lines.
Will continue doing it.
+-------------------------+------------+
|no-member |5 |
"Module 'pyodbc' has no 'connect' member" Yes it does.
"Module 'pyodbc' has no 'Error' member" Yes it does.
Issue with pylint, or pyodbc?
+-------------------------+------------+
|line-too-long |5 | meh
+-------------------------+------------+
|wrong-import-order |4 | does it matter?
+-------------------------+------------+
|missing-docstring |4 | what's the difference between
a docstring and a # comment?
+-------------------------+------------+
|superfluous-parens |3 | I like to surround 'or'
statments with parens
+-------------------------+------------+
|redefined-outer-name |3 | fixed. changed local var names.
+-------------------------+------------+
|redefined-builtin |2 | fixed. Was using 'zip' and 'id'
+-------------------------+------------+
|multiple-imports |2 | doesn't everyone?
+-------------------------+------------+
|consider-using-enumerate |2 | see below [1]
+-------------------------+------------+
|bad-builtin |2 | warning because I used filter?
+-------------------------+------------+
|unused-import |1 | fixed
+-------------------------+------------+
|unnecessary-pass |1 | fixed. left over from
Try..Except
+-------------------------+------------+
|missing-final-newline |1 | I'm using Notepad++, with
EOL Conversion set to
'Windows Format'. How
or should I fix this?
+-------------------------+------------+
|fixme |1 | a TODO statement
+-------------------------+------------+
Global evaluation
-----------------
Your code has been rated at -7.64/10
I assume -7.64 is really bad?
Has anyone ever in history gotten 10/10 from pylint for a non-trivial
program?
After fixes and disabling various warnings:
"Your code has been rated at 8.37/10"
That's about as good as it's gonna get!
[1]
pylint says "Consider using enumerate instead of iterating with range
and len"
the offending code is:
for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.
enumeration would be:
for j,item in enumerate(list1):
do something with list1[j], list2[j], list3[j], etc.
Is there an advantage to using enumerate() here?
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-05-08 03:01 +1000 |
| Message-ID | <mailman.457.1462640479.32212.python-list@python.org> |
| In reply to | #108275 |
On Sun, May 8, 2016 at 2:51 AM, DFS <nospam@dfs.com> wrote:
> [1]
> pylint says "Consider using enumerate instead of iterating with range and
> len"
>
> the offending code is:
> for j in range(len(list1)):
> do something with list1[j], list2[j], list3[j], etc.
>
> enumeration would be:
> for j,item in enumerate(list1):
> do something with list1[j], list2[j], list3[j], etc.
>
> Is there an advantage to using enumerate() here?
The suggestion from a human would be to use zip(), or possibly to
change your data structures.
for item1, item2, item3 in zip(list1, list2, list3):
do something with the items
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-07 21:16 -0400 |
| Message-ID | <ngm3qs$73r$1@dont-email.me> |
| In reply to | #108277 |
On 5/7/2016 1:01 PM, Chris Angelico wrote:
> On Sun, May 8, 2016 at 2:51 AM, DFS <nospam@dfs.com> wrote:
>> [1]
>> pylint says "Consider using enumerate instead of iterating with range and
>> len"
>>
>> the offending code is:
>> for j in range(len(list1)):
>> do something with list1[j], list2[j], list3[j], etc.
>>
>> enumeration would be:
>> for j,item in enumerate(list1):
>> do something with list1[j], list2[j], list3[j], etc.
>>
>> Is there an advantage to using enumerate() here?
>
> The suggestion from a human would be to use zip(), or possibly to
> change your data structures.
Happens like this:
address data is scraped from a website:
names = tree.xpath()
addr = tree.xpath()
I want to store the data atomically, so I parse street, city, state, and
zip into their own lists.
"1250 Peachtree Rd, Atlanta, GA 30303
street = [s.split(',')[0] for s in addr]
city = [c.split(',')[1].strip() for c in addr]
state = [s[-8:][:2] for s in addr]
zipcd = [z[-5:] for z in addr]
names = ["Taco Bell", "Wendy's"]
addr = ['928 Buford Dr, Tucker, GA 30043', '4880 Ptree Pkwy, Atlanta,
GA 30303']
street = ['928 Buford Dr', '4880 Sugarloaf Pkwy']
city = ['Tucker','Atlanta']
state = ['GA','GA']
zipcd = ['30043','30303']
When you say 'possibly change data structures'... to what?
> for item1, item2, item3 in zip(list1, list2, list3):
> do something with the items
ziplists = zip(names,street,city,state,zipcd)
print ziplists
[('Taco Bell', '928 Buford Dr', 'Tucker', 'GA', '30043'),
("Wendy's", '4880 Sugarloaf Pkwy', 'Atlanta', 'GA', '30303')]
Why is it better to zip() them up and use:
for item1, item2, item3 in zip(list1, list2, list3):
do something with the items
than
for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-05-08 11:36 +1000 |
| Message-ID | <mailman.487.1462671388.32212.python-list@python.org> |
| In reply to | #108311 |
On Sun, May 8, 2016 at 11:16 AM, DFS <nospam@dfs.com> wrote:
> On 5/7/2016 1:01 PM, Chris Angelico wrote:
>> The suggestion from a human would be to use zip(), or possibly to
>> change your data structures.
>
>
> Happens like this:
>
> address data is scraped from a website:
>
> names = tree.xpath()
> addr = tree.xpath()
>
> I want to store the data atomically, so I parse street, city, state, and zip
> into their own lists.
>
> "1250 Peachtree Rd, Atlanta, GA 30303
>
> street = [s.split(',')[0] for s in addr]
> city = [c.split(',')[1].strip() for c in addr]
> state = [s[-8:][:2] for s in addr]
> zipcd = [z[-5:] for z in addr]
So you're iterating over addr lots of times, and building separate
lists. As an alternative, you could iterate over it *once*, and have a
single object representing an address.
> Why is it better to zip() them up and use:
>
> for item1, item2, item3 in zip(list1, list2, list3):
> do something with the items
>
> than
>
>
> for j in range(len(list1)):
> do something with list1[j], list2[j], list3[j], etc.
Because 'j' is insignificant here, as is the length of the list. What
you're doing is iterating over three parallel lists - not counting
numbers. Imagine that, instead of lists, you just have *sequences* -
ordered collections of things. You can follow a recipe without knowing
the numbers of the individual lines; you just need to know the
sequence. Here, iterate over this collection:
* Collect ingredients.
* Cream the butter and the sugar.
* Sift the salt into the flour.
* Fold the mixture into an origami crane.
These instructions work whether they're numbered or not.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-07 22:15 -0400 |
| Message-ID | <ngm79s$d60$1@dont-email.me> |
| In reply to | #108313 |
On 5/7/2016 9:36 PM, Chris Angelico wrote:
> On Sun, May 8, 2016 at 11:16 AM, DFS <nospam@dfs.com> wrote:
>> On 5/7/2016 1:01 PM, Chris Angelico wrote:
>>> The suggestion from a human would be to use zip(), or possibly to
>>> change your data structures.
>>
>>
>> Happens like this:
>>
>> address data is scraped from a website:
>>
>> names = tree.xpath()
>> addr = tree.xpath()
>>
>> I want to store the data atomically, so I parse street, city, state, and zip
>> into their own lists.
>>
>> "1250 Peachtree Rd, Atlanta, GA 30303
>>
>> street = [s.split(',')[0] for s in addr]
>> city = [c.split(',')[1].strip() for c in addr]
>> state = [s[-8:][:2] for s in addr]
>> zipcd = [z[-5:] for z in addr]
>
> So you're iterating over addr lots of times, and building separate
> lists. As an alternative, you could iterate over it *once*, and have a
> single object representing an address.
I like the idea of one iteration, but how? (I'll be trying myself
before I check back in)
Remember, it's required to split the data up, to give flexibility in
sorting, searching, output, etc.
I saw a cool example where someone built a list and used it to do a bulk
INSERT. That probably won't work well here, because one of the options
I give the user is # of addresses to store. So I do invididual INSERTs
using the 'for j in range()' method, which makes it easier to track how
many addresses have been stored.
>> Why is it better to zip() them up and use:
>>
>> for item1, item2, item3 in zip(list1, list2, list3):
>> do something with the items
>>
>> than
>>
>>
>> for j in range(len(list1)):
>> do something with list1[j], list2[j], list3[j], etc.
>
> Because 'j' is insignificant here, as is the length of the list.
Sorry, but I don't understand what you mean by insignificant. j keeps
track of the position in the list - regardless of the length of the list.
> What
> you're doing is iterating over three parallel lists - not counting
> numbers. Imagine that, instead of lists, you just have *sequences* -
> ordered collections of things. You can follow a recipe without knowing
> the numbers of the individual lines; you just need to know the
> sequence. Here, iterate over this collection:
>
> * Collect ingredients.
> * Cream the butter and the sugar.
> * Sift the salt into the flour.
> * Fold the mixture into an origami crane.
>
> These instructions work whether they're numbered or not.
Again, not following you.
The only reason
for j in range(len(list1)):
do something with list1[j], list2[j], list3[j], etc.
or
for item1, item2, item3 in zip(list1, list2, list3):
do something with the items
works is because each list has the same number of items.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-05-08 12:50 +1000 |
| Message-ID | <mailman.493.1462675848.32212.python-list@python.org> |
| In reply to | #108318 |
On Sun, May 8, 2016 at 12:15 PM, DFS <nospam@dfs.com> wrote:
> On 5/7/2016 9:36 PM, Chris Angelico wrote:
>>
>> On Sun, May 8, 2016 at 11:16 AM, DFS <nospam@dfs.com> wrote:
>>>
>>> street = [s.split(',')[0] for s in addr]
>>> city = [c.split(',')[1].strip() for c in addr]
>>> state = [s[-8:][:2] for s in addr]
>>> zipcd = [z[-5:] for z in addr]
>>
>>
>> So you're iterating over addr lots of times, and building separate
>> lists. As an alternative, you could iterate over it *once*, and have a
>> single object representing an address.
>
> I like the idea of one iteration, but how? (I'll be trying myself before I
> check back in)
>
> Remember, it's required to split the data up, to give flexibility in
> sorting, searching, output, etc.
Start by unpacking the comprehensions into statement form.
street = []
for s in addr:
street.append(s.split(',')[0])
city = []
for c in addr:
city.append(c.split(',')[1].strip())
state = []
for s in addr:
state.append(s[-8:][:2])
zipcd = []
for z in addr:
zipcd.append(z[-5:])
Now see how you're doing the same thing four times? Let's start by
keeping it the way it is, but combine the loops.
street, city, state, zipcd = [], [], [], []
for a in addr:
street.append(a.split(',')[0])
city.append(a.split(',')[1].strip())
state.append(a[-8:][:2])
zipcd.append(a[-5:])
Side point: I prefer collections to be named in the plural, so these
would be "streets", and "addrs". This lets you follow a very simple
rule of iteration: "for item in collection" or "for singular in
plural". In this case, "for address in addresses" is classic
iteration.
So, now that you have a single loop picking up the different pieces,
it's easy to build up a simple object that represents an address.
# Either this
from collections import namedtuple
Address = namedtuple("Address", ["street", "city", "state", "zipcd"])
# or this
from types import SimpleNamespace
class Address(SimpleNamespace): pass
addresses = []
for a in addr:
addresses.append(Address(
street=a.split(',')[0],
city=a.split(',')[1].strip(),
state=a[-8:][:2],
zipcd=a[-5:],
)
Voila! One iteration, and a single object representing an address.
> I saw a cool example where someone built a list and used it to do a bulk
> INSERT. That probably won't work well here, because one of the options I
> give the user is # of addresses to store. So I do invididual INSERTs using
> the 'for j in range()' method, which makes it easier to track how many
> addresses have been stored.
You could slice it if you actually want that.
>>> Why is it better to zip() them up and use:
>>>
>>> for item1, item2, item3 in zip(list1, list2, list3):
>>> do something with the items
>>>
>>> than
>>>
>>>
>>> for j in range(len(list1)):
>>> do something with list1[j], list2[j], list3[j], etc.
>>
>>
>> Because 'j' is insignificant here, as is the length of the list.
>
> Sorry, but I don't understand what you mean by insignificant. j keeps track
> of the position in the list - regardless of the length of the list.
Right, but *who cares* what the position is? All you want to do is the
"do something" bit. Don't think in terms of concrete and discrete
operations in a computer; think in the abstract (what are you trying
to accomplish?), and then represent that in code.
>> What
>> you're doing is iterating over three parallel lists - not counting
>> numbers. Imagine that, instead of lists, you just have *sequences* -
>> ordered collections of things. You can follow a recipe without knowing
>> the numbers of the individual lines; you just need to know the
>> sequence. Here, iterate over this collection:
>>
>> * Collect ingredients.
>> * Cream the butter and the sugar.
>> * Sift the salt into the flour.
>> * Fold the mixture into an origami crane.
>>
>> These instructions work whether they're numbered or not.
>
> Again, not following you.
>
>
> The only reason
>
> for j in range(len(list1)):
> do something with list1[j], list2[j], list3[j], etc.
>
> or
>
> for item1, item2, item3 in zip(list1, list2, list3):
> do something with the items
>
> works is because each list has the same number of items.
Sure, but who cares what each item's position is? All that matters is
that they have corresponding positions, which is what zip() does.
Imagine you don't even have the whole lists yet. Imagine someone's
still writing stuff to them as you work. Maybe they're infinite in
length. You can't iterate up to the length of list1, because it
doesn't HAVE a length. But you can still zip it up with other parallel
collections, and iterate over them all.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-10 18:36 -0400 |
| Message-ID | <ngtnja$cni$1@dont-email.me> |
| In reply to | #108321 |
On 5/7/2016 10:50 PM, Chris Angelico wrote: > On Sun, May 8, 2016 at 12:15 PM, DFS <nospam@dfs.com> wrote: >> The only reason >> >> for j in range(len(list1)): >> do something with list1[j], list2[j], list3[j], etc. >> >> or >> >> for item1, item2, item3 in zip(list1, list2, list3): >> do something with the items >> >> works is because each list has the same number of items. > > Sure, but who cares what each item's position is? All that matters is > that they have corresponding positions, which is what zip() does. They have corresponding positions because zip() possibly truncates data! > Imagine you don't even have the whole lists yet. Imagine someone's > still writing stuff to them as you work. Maybe they're infinite in > length. You can't iterate up to the length of list1, because it > doesn't HAVE a length. But you can still zip it up with other parallel > collections, and iterate over them all. Disregarding a list of infinite length. If lists are still being created: * at every moment in time, len(list1) returns a length that doesn't change even if data is added to the list after the call to len(). Example: If the list has 100 items in it at the point len(list) is called: for i in range(len(list1)) will never iterate more than 100x, no matter how large list1 grows to. Caveat: since list1 may be bigger or smaller than the other lists at that moment in time, an error may occur when using list2[i], list3[i]. Is that all correct as you understand it? * at every moment in time, zip(list1, list2, etc) will return a fixed, same-length lists of tuples, which doesn't change even if data is added to any of the lists after the call to zip(). Example: if the lists have 100, 97 and 102 items in them at the point zip(lists) is called: for item1, item2, item3 in zip(list1, list2, list3) will never iterate beyond 97x, even if the lists grow while the enumeration is occurring. Caveat: since zip() possibly truncates lists, the results - the usage of the data - could be completely invalid. Is that all correct as you understand it? So, if that's all correct, it doesn't matter whether you use 'for i in range(len(lists))' or 'for item in zip(lists)': neither will guarantee data integrity. I haven't timed them, but as I see it, neither has a definite advantage over the other. So what I decided to do was build the lists, check that the lengths are all the same (exit the program if not), zip() them, and use enumeration because it looks less a little less clunky. I see no advantage beyond appearance.
[toc] | [prev] | [next] | [standalone]
| From | MRAB <python@mrabarnett.plus.com> |
|---|---|
| Date | 2016-05-11 02:02 +0100 |
| Message-ID | <mailman.583.1462928532.32212.python-list@python.org> |
| In reply to | #108493 |
On 2016-05-10 23:36, DFS wrote: [snip] > > If lists are still being created: > > * at every moment in time, len(list1) returns a length that doesn't > change even if data is added to the list after the call to len(). > > Example: If the list has 100 items in it at the point len(list) is called: > > for i in range(len(list1)) > > will never iterate more than 100x, no matter how large list1 grows to. > > Caveat: since list1 may be bigger or smaller than the other lists at > that moment in time, an error may occur when using list2[i], list3[i]. > > > Is that all correct as you understand it? > Yes. > > > * at every moment in time, zip(list1, list2, etc) will return a fixed, > same-length lists of tuples, which doesn't change even if data is added > to any of the lists after the call to zip(). > > Example: if the lists have 100, 97 and 102 items in them at the point > zip(lists) is called: > > for item1, item2, item3 in zip(list1, list2, list3) > > will never iterate beyond 97x, even if the lists grow while the > enumeration is occurring. > > Caveat: since zip() possibly truncates lists, the results - the usage of > the data - could be completely invalid. > > > Is that all correct as you understand it? > In Python 2, zip iterates through the arguments immediately and returns a list of tuples, so the answer is yes. In Python 3, zip returns a lazy iterator (like itertools.izip in Python 2) that gets the values from the arguments _on demand_, so the answer is no. [snip]
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hansen <me+python@ixokai.io> |
|---|---|
| Date | 2016-05-07 19:14 -0700 |
| Message-ID | <mailman.491.1462673669.32212.python-list@python.org> |
| In reply to | #108311 |
On Sat, May 7, 2016, at 06:16 PM, DFS wrote: > Why is it better to zip() them up and use: > > for item1, item2, item3 in zip(list1, list2, list3): > do something with the items > > than > > for j in range(len(list1)): > do something with list1[j], list2[j], list3[j], etc. Although Chris has a perfectly good and valid answer why conceptually the zip is better, let me put forth: the zip is simply clearer, more readable and more maintainable. This is a question of style and to a certain degree aesthetics, so is somewhat subjective, but range(len(list1)) and list1[j] are all indirection, when item1 is clearly (if given a better name then 'item1') something distinct you're working on. -- Stephen Hansen m e @ i x o k a i . i o
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-07 23:04 -0400 |
| Message-ID | <ngma4u$kgb$1@dont-email.me> |
| In reply to | #108317 |
On 5/7/2016 10:14 PM, Stephen Hansen wrote:
> On Sat, May 7, 2016, at 06:16 PM, DFS wrote:
>
>> Why is it better to zip() them up and use:
>>
>> for item1, item2, item3 in zip(list1, list2, list3):
>> do something with the items
>>
>> than
>>
>> for j in range(len(list1)):
>> do something with list1[j], list2[j], list3[j], etc.
>
> Although Chris has a perfectly good and valid answer why conceptually
> the zip is better, let me put forth: the zip is simply clearer, more
> readable and more maintainable.
>
> This is a question of style and to a certain degree aesthetics, so is
> somewhat subjective, but range(len(list1)) and list1[j] are all
> indirection, when item1 is clearly (if given a better name then 'item1')
> something distinct you're working on.
The lists I actually use are:
for j in range(len(nms)):
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
vals = nms[j],street[j],city[j],state[j],zipcd[j]
The enumerated version would be:
ziplists = zip(nms,street,city,state,zipcd)
for nm,street,city,state,zipcd in ziplists:
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
vals = nm,street,city,state,zipcd
I guess the enumeration() is a little nicer to look at. Why do you
think it's more maintainable?
Aside: I haven't tried, but is 'names' a bad idea or illegal for the
name of a python list or variable?
Thanks
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hansen <me+python@ixokai.io> |
|---|---|
| Date | 2016-05-07 20:46 -0700 |
| Message-ID | <mailman.497.1462679221.32212.python-list@python.org> |
| In reply to | #108323 |
On Sat, May 7, 2016, at 08:04 PM, DFS wrote: > The lists I actually use are: > > for j in range(len(nms)): > cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)" > vals = nms[j],street[j],city[j],state[j],zipcd[j] > > > The enumerated version would be: > > ziplists = zip(nms,street,city,state,zipcd) > for nm,street,city,state,zipcd in ziplists: > cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)" > vals = nm,street,city,state,zipcd > > > I guess the enumeration() is a little nicer to look at. Why do you > think it's more maintainable? Code is read more then its written. That which is nicer to look at, therefore, is easier to read. That which is easier to read is easier to maintain. Beyond that, its simpler, and more clearly articulates in the local space what's going on. > Aside: I haven't tried, but is 'names' a bad idea or illegal for the > name of a python list or variable? Nothing wrong with names. Or 'name', for that matter. Try to avoid abbreviations. -- Stephen Hansen m e @ i x o k a i . i o
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-08 10:26 -0400 |
| Message-ID | <ngni47$noh$1@dont-email.me> |
| In reply to | #108330 |
On 5/7/2016 11:46 PM, Stephen Hansen wrote: > On Sat, May 7, 2016, at 08:04 PM, DFS wrote: >> The lists I actually use are: >> >> for j in range(len(nms)): >> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)" >> vals = nms[j],street[j],city[j],state[j],zipcd[j] >> >> >> The enumerated version would be: >> >> ziplists = zip(nms,street,city,state,zipcd) >> for nm,street,city,state,zipcd in ziplists: >> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)" >> vals = nm,street,city,state,zipcd >> >> >> I guess the enumeration() is a little nicer to look at. Why do you >> think it's more maintainable? > > Code is read more then its written. > > That which is nicer to look at, therefore, is easier to read. > > That which is easier to read is easier to maintain. > > Beyond that, its simpler, and more clearly articulates in the local > space what's going on. That last one sounds like an art critic trying to exlain why Jackson Pollock's work doesn't suck. >> Aside: I haven't tried, but is 'names' a bad idea or illegal for the >> name of a python list or variable? > > Nothing wrong with names. Or 'name', for that matter. Try to avoid > abbreviations. np
[toc] | [prev] | [next] | [standalone]
| From | Jussi Piitulainen <jussi.piitulainen@helsinki.fi> |
|---|---|
| Date | 2016-05-08 08:50 +0300 |
| Message-ID | <lf54ma9cd4b.fsf@ling.helsinki.fi> |
| In reply to | #108323 |
DFS writes:
> The lists I actually use are:
>
> for j in range(len(nms)):
> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
> vals = nms[j],street[j],city[j],state[j],zipcd[j]
>
>
> The enumerated version would be:
>
> ziplists = zip(nms,street,city,state,zipcd)
> for nm,street,city,state,zipcd in ziplists:
> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
> vals = nm,street,city,state,zipcd
>
>
> I guess the enumeration() is a little nicer to look at. Why do you
> think it's more maintainable?
The following variations avoid the naming of the result of zip at all,
and also save a line or two, depending on what you actually do in the
loop, without introducing overly long lines. Judge for yourself.
You don't need to name the individual components, if you only actually
use vals:
for vals in zip(nms,street,city,state,zipcd):
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
Or you can opt to name the tuple and its components the other way
around:
for vals in zip(nms,street,city,state,zipcd):
nm,street,city,state,zipcd = vals
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-08 10:25 -0400 |
| Message-ID | <ngni3c$nmd$1@dont-email.me> |
| In reply to | #108340 |
On 5/8/2016 1:50 AM, Jussi Piitulainen wrote:
> DFS writes:
>
>> The lists I actually use are:
>>
>> for j in range(len(nms)):
>> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>> vals = nms[j],street[j],city[j],state[j],zipcd[j]
>>
>>
>> The enumerated version would be:
>>
>> ziplists = zip(nms,street,city,state,zipcd)
>> for nm,street,city,state,zipcd in ziplists:
>> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
>> vals = nm,street,city,state,zipcd
>>
>>
>> I guess the enumeration() is a little nicer to look at. Why do you
>> think it's more maintainable?
>
> The following variations avoid the naming of the result of zip at all,
> and also save a line or two, depending on what you actually do in the
> loop, without introducing overly long lines. Judge for yourself.
I tried:
for nm,street,city,state,zipcd in zip(nms,street,city,state,zipcd):
but felt it was too long and wordy.
> You don't need to name the individual components, if you only actually
> use vals:
>
> for vals in zip(nms,street,city,state,zipcd):
> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
I like that one. But I do one more thing (get a category ID) than just
use the vals.
--------------------------------------------------------------------
ziplists = zip(categories,names,streets,cities,states,zipcodes)
for category,name,street,city,state,zipcode in ziplists:
dupeRow, pyodbcErr = False, False
catID = getDataID("catID","CATEGORIES","catDesc",category)
cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?,?,?,?,?)"
vals =
datasrcID,searchID,catID,name,street,city,state,zipcode,str(loaddt)
try: db.execute(cSQL, vals)
except (pyodbc.Error) as programError:
if str(programError).find("UNIQUE constraint failed") > 0:
dupeRow = True
dupes +=1
print " * duplicate address found: "+name+", "+street
else:
pyodbcErr = True
print "ODBC error: %s " % programError
addrReturned += 1
if not dupeRow and not pyodbcErr:
addrSaved += 1
if addrWant != "all":
if addrSaved >= addrWant: break
conn.commit()
--------------------------------------------------------------------
That's the 'post to db' routine
> Or you can opt to name the tuple and its components the other way
> around:
>
> for vals in zip(nms,street,city,state,zipcd):
> nm,street,city,state,zipcd = vals
> cSQL = "INSERT INTO ADDRESSES VALUES (?,?,?,?,?)"
I like the first one better. python is awesome, but too many options
for doing the same thing also makes it difficult. For me, anyway.
Thanks
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-05-09 00:36 +1000 |
| Message-ID | <mailman.515.1462718166.32212.python-list@python.org> |
| In reply to | #108355 |
On Mon, May 9, 2016 at 12:25 AM, DFS <nospam@dfs.com> wrote:
> for category,name,street,city,state,zipcode in ziplists:
> try: db.execute(cSQL, vals)
> except (pyodbc.Error) as programError:
> if str(programError).find("UNIQUE constraint failed") > 0:
> dupeRow = True
> dupes +=1
> print " * duplicate address found: "+name+", "+street
> else:
> pyodbcErr = True
> print "ODBC error: %s " % programError
> conn.commit()
> --------------------------------------------------------------------
>
... and then you just commit???!?
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-08 11:06 -0400 |
| Message-ID | <ngnker$vmc$1@dont-email.me> |
| In reply to | #108357 |
On 5/8/2016 10:36 AM, Chris Angelico wrote:
> On Mon, May 9, 2016 at 12:25 AM, DFS <nospam@dfs.com> wrote:
>> for category,name,street,city,state,zipcode in ziplists:
>> try: db.execute(cSQL, vals)
>> except (pyodbc.Error) as programError:
>> if str(programError).find("UNIQUE constraint failed") > 0:
>> dupeRow = True
>> dupes +=1
>> print " * duplicate address found: "+name+", "+street
>> else:
>> pyodbcErr = True
>> print "ODBC error: %s " % programError
>> conn.commit()
>> --------------------------------------------------------------------
>>
>
> ... and then you just commit???!?
>
> ChrisA
That's what commit() does.
[toc] | [prev] | [next] | [standalone]
| From | Stephen Hansen <me+python@ixokai.io> |
|---|---|
| Date | 2016-05-08 08:15 -0700 |
| Message-ID | <mailman.517.1462720538.32212.python-list@python.org> |
| In reply to | #108358 |
On Sun, May 8, 2016, at 08:06 AM, DFS wrote: > On 5/8/2016 10:36 AM, Chris Angelico wrote: > > ... and then you just commit???!? > > > > That's what commit() does. > I assure you, he knows what commit does :) The point is, you don't usually commit after an error happens. You rollback. Or correct the data. Since the data didn't go in, there should (in theory) be nothing TO commit if an error happens. Or, there should be partial data in that needs a rollback before you decide to do something else. -- Stephen Hansen m e @ i x o k a i . i o
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2016-05-09 13:17 +1200 |
| Message-ID | <dpa6pqF6egaU1@mid.individual.net> |
| In reply to | #108361 |
Stephen Hansen wrote: > The point is, you don't usually commit after an error happens. You > rollback. He might want to commit the ones that *did* go in. That's not necessarily wrong. It all depends on the surrounding requirements and workflow. -- Greg
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-05-09 12:18 +1000 |
| Message-ID | <mailman.539.1462760302.32212.python-list@python.org> |
| In reply to | #108401 |
On Mon, May 9, 2016 at 11:17 AM, Gregory Ewing <greg.ewing@canterbury.ac.nz> wrote: > Stephen Hansen wrote: >> >> The point is, you don't usually commit after an error happens. You >> rollback. > > > He might want to commit the ones that *did* go in. > That's not necessarily wrong. It all depends on the > surrounding requirements and workflow. If that's the case, they should probably be being committed part way. Generally, once the transaction state is in error, further operations can't be done. (At least, that's how it is with *good* database backends. I don't know what MySQL does.) ChrisA
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2016-05-08 22:58 -0400 |
| Message-ID | <ngou6p$aip$1@dont-email.me> |
| In reply to | #108401 |
On 5/8/2016 9:17 PM, Gregory Ewing wrote: > Stephen Hansen wrote: >> The point is, you don't usually commit after an error happens. You >> rollback. > > He might want to commit the ones that *did* go in. > That's not necessarily wrong. It all depends on the > surrounding requirements and workflow. Bingo.
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.python
csiph-web