简体   繁体   中英

Dataquest: I've just learned how to define a function in python. Now I want to run it in a loop.

I am a python beginner and I learn using dataquest. I want to use a self-defined function in a loop to check every item in a list, whether it is a color movie or not and add the results (True, False) to a list. Right now the function returns False only, also way to many times. Any hints what I did wrong?

wonder_woman = ['Wonder Woman','Patty Jenkins','Color',141,'Gal Gadot','English','USA',2017]

def is_usa(input_lst):
    if input_lst[6] == "USA":
        return True
    else:
        return False

def index_equals_str(input_lst, index, input_str):
    if input_lst[index] == input_str:
        return True
    else:
        return False

wonder_woman_in_color = index_equals_str(input_str="Color", index=2, input_lst=wonder_woman)

# End of dataquest challenge

# My own try to use the function in a loop and add the results to a list

f = open("movie_metadata.csv", "r")
data = f.read()
rows = data.split("\n")
aufbereitet = []

for row in rows:
    einmalig = row.split(",")
    aufbereitet.append(einmalig)
# print(aufbereitet)

finale_liste = []

for item in aufbereitet:
    test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)
    finale_liste.append(test)

print(finale_liste)

Also at pastebin: https://pastebin.com/AESjdirL

I appreciate your help!

The problem is in this line

test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)

The input_lst argument should be input_lst=item . Right now you are passing the whole list of lists to your function everytime.

The .csv file is not provided but I assume the reading is correct and it returns a list like the one you provided in the first line of your code; in particular, that you are trying to pack the data in a list of lists (the einmalig variable is a list obtained by the row of the csv file, then you append each einmalig you find in another list, aufbereitet).

The problem is not in the function itself but in the parameters you give as inputs: when you do

test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)

you should see that the third parameter is not a list corresponding to the single movie data but the whole list of movies. This means that the Python interpreter, in the function, does this iteration for every item in aufbereitet (that is, iterates for n times where n is aufbereitet's length):

if aufbereitet[2] == "Color":
    return True
else:
    return False

It is clear that even if the movie is in color, the comparison between a list (an element of aufbereitet) and a string returns False by default since they are different types.

To correct the issue just change the line

test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)

with

test = index_equals_str(input_str="Color", index=2, input_lst=item)

since, when you use the for loop in that way, the variable item changes at each iteration with the elements in aufbereitet.

Notice that if you're learning that's still ok to use functions but you can use an inline version of the algorithm (that's what Python is famous for). Using

finale_liste = [item[2] == "Color" for item in aufbereitet]

you obtain the list without going to define a function and without using the for loop. That's called list comprehension.

Another thing you can do to make the code more Pythonic - if you want to use the functions anyway - is to do something like

def index_equals_str(input_lst, index, input_str):
    return input_lst[index] == input_str

that has the same result with less lines.

Functional programming is sometimes more readable and adaptable for such tasks:

from functools import partial

def index_equals_str(input_lst, index=1, input_str='Null'):
    return input_lst[index] == input_str

input_data = [['Name1', 'Category1', 'Color', 'Language1'],
              ['Name2', 'Category2', 'BW', 'Language2']]

result = list(map(partial(index_equals_str, input_str='Color', index=2), input_data))

# output
# [True, False]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM