Reputation: 35
my code consists of me recreating the function 'filter()' and using it with a function to filter words longer than 5 characters. It worked with the actual function filter when I tried it btw...I'm using python 3+
def filter1(fn, a):
i = 0
while i != len(a):
u = i - 1
a[i] = fn(a[i], a[u])
i += 1
return a
def filter_long_words(l):
if len[l] > 5:
return [l]
listered = ['blue', 'hdfdhsf', 'dsfjbdsf', 'jole']
print(list(filter1(filter_long_words, listered)))
getting error
TypeError: filter_long_words() takes 1 positional argument but 2 were given
Upvotes: 0
Views: 73
Reputation: 5537
Your're calling fn
with 2 parameters in filter1(fn, a)
, and since you've passed filter_long_words()
to filter1
as fn
, that triggers the error.
But there's more weird stuff:
I don't understand the magick of filter1
or what you were trying to
accomplish, but it seems to me that you don't have a clear idea what to do.
But if you want to mimic (somehow) how filter
works, you have to return a
list which contains only items for which the fn
function returns true. When
you know this, you can rewrite it - here are a few suggestions for rewrite
# explicit, inefficient and long, but straightforward version:
def filter1(fn, a):
new_list = []
for item in a:
if fn(item):
new_list.append(item):
return new_list
# shorter version using list comprehensions:
def filter1(fn, a):
return [item for item in a if fn(item)]
The filter_long_words
function is wrong too - it should return True or
False. The only reason why it could work is because any non-empty list is
treated as True
by python and default return value of a function is None
,
which translates to False. But it's confusing and syntactically wrong to use
len[l]
- the proper usage is len(l)
.
There are a few suggestions for rewrite, which all returns explicit boolean
values:
# unnecessary long, but self-explanatory:
def filter_long_words(l):
if len(l) > 5:
return True
else
return False
# short variant
def filter_long_words(l):
return len(l) > 5
Upvotes: 1
Reputation: 15537
You are passing two parameters to fn
(which refers to filter_long_words
) here:
a[i] = fn(a[i], a[u])
But filter_long_words
only accepts one parameter.
Notes:
for item in my_list
, or if you want index as well for index, item in enumerate(my_list)
.IndexError
since u
will be -1
in the first round of your loop.filter
function can also be expressed as a list comprehension: (item for item in listered if filter_long_words(item))
My version of filter
would look like this, if I have to use a for
loop:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
for item in sequence:
if fn(item):
yield item
Since you have stated that you are using Python 3, this returns a generator instead of a list. If you want it to return a list:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
acc = []
for item in sequence:
if fn(item):
acc.append(item)
return acc
If you don't need to use a for
loop:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
return (item for item in sequence if fn(item))
Upvotes: 1
Reputation: 974
You are calling "filter_long_words" with 2 parameter => fn(a[i], a[u]) also there is an error
def filter_long_words(l):
if **len[l]** > 5:
return [l]
len is builtin method it should be len(l)
Upvotes: 0