Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #108275 > unrolled thread

pylint woes

Started byDFS <nospam@dfs.com>
First post2016-05-07 12:51 -0400
Last post2016-05-08 18:24 -0400
Articles 20 on this page of 69 — 19 participants

Back to article view | Back to comp.lang.python


Contents

  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 →


#108275 — pylint woes

FromDFS <nospam@dfs.com>
Date2016-05-07 12:51 -0400
Subjectpylint 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]


#108277

FromChris Angelico <rosuav@gmail.com>
Date2016-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]


#108311

FromDFS <nospam@dfs.com>
Date2016-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]


#108313

FromChris Angelico <rosuav@gmail.com>
Date2016-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]


#108318

FromDFS <nospam@dfs.com>
Date2016-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]


#108321

FromChris Angelico <rosuav@gmail.com>
Date2016-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]


#108493

FromDFS <nospam@dfs.com>
Date2016-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]


#108508

FromMRAB <python@mrabarnett.plus.com>
Date2016-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]


#108317

FromStephen Hansen <me+python@ixokai.io>
Date2016-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]


#108323

FromDFS <nospam@dfs.com>
Date2016-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]


#108330

FromStephen Hansen <me+python@ixokai.io>
Date2016-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]


#108356

FromDFS <nospam@dfs.com>
Date2016-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]


#108340

FromJussi Piitulainen <jussi.piitulainen@helsinki.fi>
Date2016-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]


#108355

FromDFS <nospam@dfs.com>
Date2016-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]


#108357

FromChris Angelico <rosuav@gmail.com>
Date2016-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]


#108358

FromDFS <nospam@dfs.com>
Date2016-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]


#108361

FromStephen Hansen <me+python@ixokai.io>
Date2016-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]


#108401

FromGregory Ewing <greg.ewing@canterbury.ac.nz>
Date2016-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]


#108404

FromChris Angelico <rosuav@gmail.com>
Date2016-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]


#108405

FromDFS <nospam@dfs.com>
Date2016-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