Dictionary instantiation?

Bruno Desthuilliers bruno.42.desthuilliers at wtf.websiteburo.oops.com
Fri Dec 7 05:56:14 EST 2007


Matt_D a écrit :
(snip)
> Another newb question, same project:
> 
> #Fetch author names
> def rem_blank_authors(): #Function to remove entries with '' in the
> AUTHOR field of the .csv
>     csv_list = list(csv_file) #Convert the open file to list format
> for e-z mode editing
>     for row in csv_list:
>         author_name = row[-1]
>         if author_name == '': #Find entries where no author is listed
>             csv_list.remove(row) #Remove those entries from the list
>         return csv_list

The return statement being in the for block, this will always return at 
the end of the first iteration. Which is obviously not what you want !-)

Hint : the return statement should be at the same indentation level as 
the for statement.

Also, modifying a sequence in place while iterating over it is a *very* 
bad idea. The canonical solution is to build a new sequence based on the 
original. or, if working on an iterator, to write a filtering iterator, ie:

def rem_blank_authors(csv_file):
     for row in csv_list:
         author_name = row[-1]
         if author_name.strip() != '':
	    yield row


Now you can use it as:

for row in rem_blank_authors(csv_file)):
   assert(row[-1].strip() != '')


> def author_to_dict():

def author_to_dict(csv_file):

>     for row in csv_file:

        for row in rem_blank_authors(csv_file)):
>         author_count = row[-1]

Why naming it 'author_count' when it's the author name ?

           author_name = row[-1]

You're inside a fonction, which has it's own namespace, so this won't 
clash with local names of other functions !-)

>         if author_count in story_per_author:
>             story_per_author[author_count] += 1
>         else:
>             story_per_author[author_count] = 1

          if author_name in story_per_author:
              story_per_author[author_name] += 1
          else:
              story_per_author[author_name] = 1

Not very important but might be good to know: if the general case is 
that each author is found several times in a csv file, you might get 
better results using a try/except block:

          try:
              story_per_author[author_name] += 1
          except KeyError:
              story_per_author[author_name] = 1


>     return story_per_author

> 
> The solution provided for my previous post worked out. Now I'm testing
> the author_to_dict function, modified to get an accurate count of
> stories each author has written. Now, if I call rem_blank_authors,
> story_per_author == {}. But if I #comment out that line, it returns
> the expected key values in story_per_author. What is happening in
> rem_blank_authors that is returning no keys in the dictionary?
> 

You already consumed the whole csv_file iterator.

> I'm afraid I don't really understand the mechanics of "return" 

It's an entirely different problem.

> and
> searching the docs hasn't yielded too much help since "return" is such
> a common word (in both the Python 2.5 docs and Dive Into Python).

heck, not only in Python - this is really CS101.

For short: the return statemement terminates the function execution. 
Also, the object (if any) following the return statement will be the 
"return value" of the function, that is the value returned to the 
caller. If no value is given, the return value will be the None object 
(which is Python's generic 'null' value). If the function ends without a 
n explicit return, it's return value will also be None.

> I
> realize I should probably RTFM, but honestly, I have tried and can't
> find a good answer. Can I get a down and dirty explanation of exactly
> what "return" does? And why it's sometimes "return" and sometimes it
> has an argument? (i.e. "return" vs. "return author_of_title")

cf above.

Dummy exemples:

def add(num1, num2):
   return num1 + num2

x = add(1, 2)
print x

def say_hello_to_jim(name):
    if name == 'jim':
      return "Hello Jim"
    # implicit 'return None' here

names = ['bob', 'will', 'jim', 'al']
for name in names:
   print say_hello_to_jim(name)

HTH



More information about the Python-list mailing list