SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)

    Undefined variable assignment to list

    So I've just started playing around with python. My first script was to spool through a pipe deliminated csv.

    I noticed this language is slightly more strict than PHP I receive an error when trying to assign a non existant variable to a new list.

    Code Python:
    #open csv file
    ifile  = open('/tmp/file.dat', "rb")
    reader = csv.reader(ifile,delimiter='|')
    for row in reader:
         op = {
              'column': row[4]
          }

    If row[4] happens to be null for that row, then it will error out. I've come across a few solutions such as setdefault. But I'm curious how some of your setups might be, especially for something dynamic like spooling a csv.

  2. #2
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,271
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    I notice the Python code around me does lots and lots and lots of try-excepts. Which I guess is good. The main thing with those being, to keepy the try parts as small as possible... some people stuff everything into their try statements which is a bit dumb since now there could be many different types of exceptions that your 'except' won't catch. I do the bare-minimum test in my try's and then after the except, I stuff everything else in the Else.

    A non-Pythonic answer I've seen states a regex to match the value against in an if statement before attempting assignment. That seems more Perlish really.

    In many instances where there are classes and defs, the arguments fed to it are keyword vars with var=None as a default... that's super common.

    One thing I really liked going from Javascript to Python is the named variables and default var values in functions.

  3. #3
    SitePoint Member
    Join Date
    Feb 2013
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    As Stomme said, try using try-excepts, or test for the presence of what you've been returned (the example below is terrible, but you can do it if you *really* want):
    Code:
    if 4 < len(row):
           do_something()
    See here for more info: http://stackoverflow.com/a/8570694

  4. #4
    SitePoint Member
    Join Date
    Feb 2013
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by K. Wolfe View Post
    So I've just started playing around with python. My first script was to spool through a pipe deliminated csv.

    I noticed this language is slightly more strict than PHP I receive an error when trying to assign a non existant variable to a new list.

    Code Python:
    #open csv file
    ifile  = open('/tmp/file.dat', "rb")
    reader = csv.reader(ifile,delimiter='|')
    for row in reader:
         op = {
              'column': row[4]
          }

    If row[4] happens to be null for that row, then it will error out. I've come across a few solutions such as setdefault. But I'm curious how some of your setups might be, especially for something dynamic like spooling a csv.
    I would use the following approach

    Code Python:
    import csv
    ifile  = open('/tmp/file.dat', "rb")
    reader = csv.reader(ifile,delimiter='|')
    column_values = [row[4] if len(row) > 4 else None for row in reader]

    This uses a list comprehension (which is neater and faster than a for loop) and returns all the values of column 5 as a list.
    Also, you are assigning the value of row[4] to a dictionary in your example code, so a list comprehension may not suit your use case in this instance. However, I would personally gather the desired values first, then perform operations on them, which is why I have used a list comprehension here.

    My example doesn't use try/except
    try/except is usually pretty fast, unless the exception is triggered - see how fast are exceptions
    In this case I assume the exception will be triggered, and thus the check for len(row) is the better option. You would only know which method was faster by profiling your particular code and data, which I have not done in this case. In general I avoid using try / except (unless it makes more sense than a conditional check).

    If list comprehensions tickle your fancy, also check out generators. For this problem I would actually use a generator not a list comprehension, but as you are a beginner a list comprehension is probably an easier way to be introduced to the concepts at play.

    Hopefully this makes sense and suits your needs.

  5. #5
    SitePoint Member
    Join Date
    Feb 2013
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by cxz View Post
    As Stomme said, try using try-excepts, or test for the presence of what you've been returned (the example below is terrible, but you can do it if you *really* want):
    Code:
    if 4 < len(row):
           do_something()
    See here for more info: http://stackoverflow.com/a/8570694
    Great point made here about python and preferring Easier To Ask For Forgiveness Than Permission vs Look Before You Leap

    Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
    It's very common to use try/except in python code, so please don't interpret my preference to 'only use them where it makes sense' as 'use try/except sparingly', just that I prefer not to use a short for loop when I can use a list comprehension.

    Code style is an interesting thing.

  6. #6
    Always A Novice bronze trophy
    K. Wolfe's Avatar
    Join Date
    Nov 2003
    Location
    Columbus, OH
    Posts
    2,178
    Mentioned
    63 Post(s)
    Tagged
    2 Thread(s)
    Well I guess I provided a bad example. Im not referring to adding a single item. I'm referring to doing an operation for each item in row, not just row[4].

  7. #7
    om nom nom nom Stomme poes's Avatar
    Join Date
    Aug 2007
    Location
    Netherlands
    Posts
    10,271
    Mentioned
    50 Post(s)
    Tagged
    2 Thread(s)
    You could still use the list comprehension, with a variable in place of the 4.
    Since I don't think in list comprehensions, I usually write out first two for loops, one nested in the other. Then I can change that around into a list comp.

    Pythonistas encourage list comprehensions over for loops and for loops over while loops because people have been tweaking the interpreter to be more efficient with those, so in many cases they're the fastest option (use timeit to check any given case, though I've seen people on LinkedIn showing differences between for example 32- and 64-bit architecture...).

    Off-topic,
    There's a French dude on SO, e-satis, who has a couple of really nice "answers" describing decorators and generators, with code details and everything. Look him up, they're fun to read.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •