AlexW.H.B.
AlexW.H.B.

Reputation: 1871

how to get python to return a list?

So I'm writing a python script that will clean file names of useless and unwanted characters, but I'm running into a problem, I can't seem to figure out how to return a list or dictionary with all of the items in it that I iterated over. it only returns the first item I iterated over. this is my first time writing in python. any help would be greatly appreciated. I'm mostly writing this to learn. the clean_title() method is the one I'm trying to return from. and I call it at the bottom.

import os
import re

# here is how all my video files will look after this
# show name Season 1 Episode 1

filename = os.listdir("E:/Videos/TV/tv-show")



def clean_title(filename):
    name = {}
    for title in filename:
        n_title = title.split('.')
        index = [i for i, item in enumerate(n_title) if re.search('\w\d{2}\w\d{2}', item)]
        if len(index) > 0:
            name = {'title':n_title[0:index[0]], 'ep_info':n_title[index[0]]}
            return name


def get_show_name(filename):
    pass


def update_title():
    #show_title = get_show_name + ' ' + get_episode_info
    #print show_title


if __name__=="__main__":
    test = clean_title(filename)
    print test

Upvotes: 0

Views: 157

Answers (4)

Larry Lustig
Larry Lustig

Reputation: 50970

You have two distinct problems.

The first is that you're returning from inside your loop, so you will only have processed a single iteration of the loop when you hit the return statement. That's why it looks like you're getting the first iterated value when, in fact, you're never reaching the other iterations.

You can fix this by out-denting the return statement to the correct level.

The second problem is in the way you're accruing your results to return from clean_title(). You are only ever storing a single cleaned title in the name variable. Each time through the loop you're overwriting the previously calculated title with the new one from that iteration. Even if you fix the return issue, the current version would then return the last title you computed.

You can accrue your results in either a list or a dictionary. If a list, you initialize with name = [] and add new titles with name.append(title_goes_here). If you want to accrue your results in a dictionary, you initialize with name = {} and add new titles with name[index_goes_here] = title_goes_here. Note that in the case of a dictionary you need to have some logical key value (usually an integer or string) that you will use to recover the value later on.

Finally, I have to add that I find your use of singular case (filename, title, clean_title) for plural objects and actions to be confusing. I'd call a list of file names filenames, and so on.

Upvotes: 2

avasal
avasal

Reputation: 14854

  1. your indentation of return name is wrong, pull it out to be at the same level as name={} statement
  2. title should not be a string it should a variable from the for loop

It is currently under if condition, hence as soon as the condition is true, after processing the statements in the condition return will be executed

def clean_title(filename):
    name_list = []
    for title in filename:
        n_title = title.split('.')
        index = [i for i, item in enumerate(n_title) if re.search('\w\d{2}\w\d{2}', item)]
        if len(index) > 0:
            # you should store the dictionary in the lists, as all the dictionaries will contain the common keys of `ep_info`
            name_list.append({title:n_title[0:index[0]], 'ep_info':n_title[index[0]]})
    return name_list # look here

Upvotes: 1

tacaswell
tacaswell

Reputation: 87376

The loop will exit as soon as it hits the return. I suspect what you want to do is

def clean_title(filename):
    names = []
    for title in filename:
        n_title = title.split('.')
        index = [i for i, item in enumerate(n_title) if re.search('\w\d{2}\w\d{2}', item)]
        if len(index) > 0:
            names.append({'title':n_title[0:index[0]], 'ep_info':n_title[index[0]]})
    return names    

which will return a list of dict objects with two keys, title and ep_info, each.

Upvotes: 1

Alex L
Alex L

Reputation: 8925

You're returning after having looked at only the first title in filename

def clean_title(filename):
    # ...
    for title in filename:
        # ...
        if len(index) > 0:
            # ...
            return name

I suggest making clean_title take only a single filename, and looping through each file as follows:

filenames = os.listdir("E:/Videos/TV/tv-show")
for filename in filenames:
    new_filename = clean_title(filename)
    # Rename file

Upvotes: 1

Related Questions