Having issue in the follwing code, it looks like I am facing issue with either list or int operations, so where and how should I do the changes to correct this code:
cube = lambda x:x**3
def fibonacci(n):
fb=[0,1]
for i in range(2,n-1):
fb.append([fibonacci(i-1)+fibonacci(i-2)])
return fb
if __name__ == '__main__':
n = int(input())
print(list(map(cube, fibonacci(n))))
Error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-761cca8f2b48> in <module>
7 if __name__ == '__main__':
8 n = int(input())
----> 9 print(list(map(cube, fibonacci(n))))
<ipython-input-9-761cca8f2b48> in <lambda>(x)
----> 1 cube = lambda x:x**3
2 def fibonacci(n):
3 fb=[0,1]
4 for i in range(2,n-1):
5 fb.append([fibonacci(i-1)+fibonacci(i-2)])
TypeError: unsupported operand type(s) for ** or pow(): 'list' and 'int'
You should be certain what you want fibonacci() to return. It looks like you want it to return a list since you are passing the result to map(). If so, the recursive calls will also return a list, to this line doesn't really make sense:
fb.append([fibonacci(i-1)+fibonacci(i-2)])
because fibonacci(i-1) and fibonacci(i-2) are also lists, but it looks like you expect an integer here as a result of the addition.
Since you are using a loop in the function and have a seed list, you don't need the recursion. Just index into the list fb:
def fibonacci(n):
fb=[0,1]
for i in range(2,n-1):
fb.append(fb[i-1] + fb[i-2])
return fb
n = 9
fibonacci(n)
# [0, 1, 1, 2, 3, 5, 8, 13]
With that, your cube map() should work.
You might want to replace
fb.append([fibonacci(i-1)+fibonacci(i-2)])
with
fb.append(fibonacci(i-1)+fibonacci(i-2))
Right now, you are mapping a function that takes a scalar as input onto a list containing both numbers like 0 and 1 as well as lists, like [1], for example.
Related
I am getting an error when running the following code:
def f(x):
return x**3-x-2
def bisection(f,a,b,app=0.3):
Fa,Fb=f(a),f(b)
if Fa*Fb>0:
raise Exception('Fails')
for i in range(a,b):
x=(a+b)/2
if f*Fa>0:
a=x
else:
b=x
return x
print(bisection(f,{'a':1,'b':2},0.00003))
Below the output I get when running the script above:
TypeError: unsupported operand type(s) for ** or pow(): 'dict' and 'int'
Any ideas on how to solve this?
There are a couple of issues here. In the bisection function you are supposed to give 4 arguments, f which is a function, a and b which are numbers, and a fourth argument app which is not used in your function currently.
The first issue is that you are giving a dictionary instead of the a and b arguments. The following will work better.
bisection(f=f,a=1,b=2,app=0.00003)
I do not know the bisection method, but from what I can tell from a quick scan on the bisection method from Wikipedia, it should be an N_MAX variable which tells how many iterations you will allow before breaking.
Therefore you should not use a for loop and use a while loop instead.
The new algorithm is then
def f(x):
return x**3-x-2
def bisection(f,a,b,app=0.3, N_MAX=10):
Fa,Fb=f(a),f(b)
if Fa*Fb>0:
raise Exception('Fails')
n = 0
while n < N_MAX:
x=(a+b)/2
if f(x)==0 or ((a-b)/2) < app:
return x
n += 1
if f(x) > 0:
a = x
else:
b = x
return x
print(bisection(f,1,2,0.00003, 10))
>>> 1.5
I'm trying to compare sum of first and last element in a list, second to second last, and so on.
The list has even number of numbers.
But when I call the max() function on a list, it gives me an error. Help me
li = [12,31,51,72,93,11,132,151,172,144]
sum1 = []
for i in range(len(li)):
sum1.append(li[i] + li[len(li)-1-i])
print(sum1)
print(max(sum1))
and the error is:
TypeError Traceback (most recent call last)
<ipython-input-34-04d301659610> in <module>
5 sum1.append(li[i] + li[len(li)-1-i])
6 print(sum1)
----> 7 print(max(sum1))
8
TypeError: 'int' object is not callable
it is possible that you have shadowed the built-function, you can use:
print(__builtin__.max(sum1))
in this way you will use the max function that you want
Note: I know python is strongly typed and we wont concatenate 2 different types. but accidentally i have tried,
I got different result,
a = []
>>>a=a+1 #it gives me expected concatenate error
TypeError: can only concatenate list (not "int") to list
>>>a+=1 #but this wasn't
TypeError: 'int' object is not iterable
This is because operator + and operator += is not same magic function implement in list class.
__iadd__() ## Map to += Operator
__add__() ## Map to + Operator
That means you trigger different magic function of list object.
From what I gather while doing experimentation is that.
a = a + 1 is concatenating a list and an integer, but as we know + operator or concatenation requires two lists, hence the error we get is
TypeError: can only concatenate list (not "range") to list, as we can see below
In [43]: [] + 1
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-43-67dee89361ae> in <module>
----> 1 [] + 1
TypeError: can only concatenate list (not "int") to list
In [47]: [] + []
Out[47]: []
In a += 1, we internally call a.extend(1) as per the docs: https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
s.extend(t) or s += t .
extends s with the contents of t (for the most part the same as s[len(s):len(s)] = t)
Also from the docs at: https://docs.python.org/3/tutorial/datastructures.html
list.extend(iterable)
Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.
So 1 is being treated as an iterable, but since int is not an iterable, we get the error TypeError: 'int' object is not iterable as we can see below
In [49]: a = []
In [50]: a.extend(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-50-4671950943e4> in <module>
----> 1 a.extend(1)
TypeError: 'int' object is not iterable
As stated the two operators do not map to the same magic function. And the two have different implementations. This has some interesting consequences. the normal plus (+ or __add__) expects another list to concatenate whereas in-place add (+= or __iadd__) is more allowing and can take any iterator and make it into a list before adding:
a = []
a = a + range(2)
TypeError: can only concatenate list (not "range") to list
a += range(2)
[0, 1]
I don't know why this is though.
I'm python user and I'm evaluate combination in python.
For two integers m,n, nCm=n!/(m!*(n-m)!)
So, I defined factorial and combination function.
factorial function is working, but combination function does not working.
What is the error?
1> Factorial Function
def factorial(a):
f=1
for i in range(1,a+1):
f=f*i
print(f)
2> Combination Function
def Combination(n,m):
fn=factorial(n)
fm=factorial(m)
fnm=factorial(n-m)
ncm=factorial(n)/(factorial(m)*factorial(n-m))
print(ncm)
In factorial function, For example, factorial(4)=24 is working in python.
But, In combination function,
When I typing Combination(4,2),
24
2
2
24
2
2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-18-daae2b10838c> in <module>()
----> 1 Combination(4,2)
<ipython-input-17-76c6e425ad35> in Combination(n, m)
3 fm=factorial(m)
4 fnm=factorial(n-m)
----> 5 ncm=factorial(n)/(factorial(m)*factorial(n-m))
6 print(ncm)
7
TypeError: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
What's the matter in my coding?
Instead of printing the output of a function, you should return the result.
def factorial(a):
f=1
for i in range(1,a+1):
f=f*i
return f
def combination(n,m):
return = factorial(n)/(factorial(m)*factorial(n-m))
print combination(4,2)
One more remark: after calculating factorial(n), it will be stored in your fn variable. You shouldn't calculate it again, but rather take that value and "recycle" it.
def factorial(a):
f=1
for i in range(1,a+1):
f=f*i
return f
def Combination(n,m):
fn=factorial(n)
fm=factorial(m)
fnm=factorial(n-m)
ncm=fn/(fm*fnm)
print(ncm)
Combination(4,2)
In your code there is missing return statement in factorial function.
I am trying to learn python reduce function.
This is some code that does not make sense to me
>>> x = [1,2,3]
>>> reduce(sum, [b for b in x if b > 0])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> reduce(sum, [b for b in x if b > 2])
3
Why does it work when b > 2 but not b > 0
The code seems almost exactly the same
In the second case the list you created with list comprehension has only one element, so it is not reduced. This reduction doesn't fail, because there is nothing to be reduced there, so function sum isn't executed and it doesn't fail. The result is the only integer, that has been there before.
The function sum is defined in the documentation. As you can see, it is supposed to sum values in some iterable container, such as list or tuple. You could write sum([1,2,3]) and it would work just like this reduction, that you want to make. If you want to achieve this result with using the reduction function, you have to make sure, that you have a function, that takes two integers and returns their sum.
Here you have such function:
def sum2(x, y):
return x + y
Reduce with such function should give you expected results.
sum2 = lambda x, y: x+y
The following function does the same, but is shorter and nicer due to lambda notation, it might be nice to look at it sometime in the future, if you don't know it yet.
From the docs about reduce:
Apply function of two arguments cumulatively to the items of iterable,
from left to right, so as to reduce the iterable to a single value
So in the first case, you have used reduce wrongly by using the builtin sum which does not take two arguments but an iterable. sum consumes the iterable in the first iteration of reduce and returns an int which is not further reduceable.
In the second case, sum is not even called on the iterable:
If initializer is not given and iterable contains only one item, the
first item is returned.
Since iterable is of length 1, reduce returns the one item in the iterable and sum does not nothing.
Input in second code snippet is single element list - it's a degenerated case where callable isn't even called.
Consider following example:
def my_sum(*args):
print "my_sum called with", args
return sum(*args)
x = [1, 2, 3]
reduce(my_sum, [b for b in x if b > 2])
# nothing gets printed, value 3 is returned, since it's only element in list
Now consider your failed case:
reduce(my_sum, [b for b in x if b > 0])
Output is:
my_sum called with (1, 2)
[exception traceback]
Equivalent call to builtin sum is sum(1, 2), which results in same exception as quoted by you.
sum signature does not follow rules for reduce function. sum(iterable[, start]) takes two arguments (as expected), but first of them has to be iterable, where second is optional initial value.
reduce requires function to take two arguments, where (quoting docs):
The left argument, x, is the accumulated value and the right argument,
y, is the update value from the iterable.
We can clearly see that these interfaces are not conform with each other. Correct callable will be something like:
def reduce_sum(accumulator, new_value):
return accumulator + new_value
reduce(reduce_sum, [b for b in x if b > 0])
As Moses points out "sum consumes the iterable in the first iteration"
so let's play with it
>>> sum(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
>>> sum([1,2])
3
>>> sum(x)
6
>>> sum([b for b in x if b >0])
6
>>> reduce(lambda x, y: x+y, x)
6
>>> reduce(lambda x, y: x+y, [b for b in x if b > 0])
6
>>> reduce(lambda x, y: x+y, [b for b in x if b > 1])
5
The reduce function takes in a function and an iterable.
It then maps each element of that iterable to the function.
What your first b > 0 function is doing is trying to run sum with 2 arguments. One argument being the accumulated total, and the other being an element of the input list, for example it would look like: sum(0, 1).
This is stated in the documentation as:
Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. ... The left argument, is the accumulated value and the right argument, is the update value from the iterable.
What your second b > 2 function is doing is simply running the reduce function with an iterator containing one item, which does not attempt to apply sum as stated in the documentation.
If initializer is not given and iterable contains only one item, the first item is returned.
But since sum takes in an iterable, you could just do:
sum([b for b in x if b > 0])