My first script doesn't return the result of the whole input list, and the second one doesnt return iterable tuple. Any advice?
input= [0.1, 0.2]
def newvalue():
for i in input:
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
return value[0]
print(newvalue()) #1.8229239584193715
If I use the following script it does the work and it prints all the values which results from the input list, but the problem with this script that I can't iterate through the calculated values.
for i in input:
value = integrate.quad(lambda i: (np.exp(-i)) / i, i, np.inf)
print(value[0]) #1.8229239584193715
#1.2226505441838773
As said in the comments, you need to create a loop and append the values inside just like so:
import numpy as np
from scipy import integrate
input_= [0.1, 0.2]
def newvalue():
values = []
for i in input_:
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
values.append(value[0])
return values
print(newvalue()) #[1.8229239584193715, 1.2226505441838773]
The first script only provides one value because you have a return in the loop — the loop doesn’t continue after that.
There are two typical ways to handle this situation. The first is to create an empty array before your loop, add each result to the array during the loop, and return that results array after the loop. That approach is ok if the number of values / loops is small, i.e. you don’t want to build up a 10,000,000 element array.
If the number of values / loops is bigger, or if your outer function may not need all the values, use a yield in place of your return. That allows the called function to generate each value as needed when called from an outer loop.
After calling return statements the function does not continue and all information is lost that has not been either returned or is not referenced by a variable outside the function scope.
The answer from Anwarvic should do the trick.
Your function should not take it's argument from a global variable.
You can define your function so that it accepts one value, and returns the caluclated result for this value.
def newvalue(input):
value=integrate.quad(lambda i:(np.exp(-i))/i,i,np.inf)
return value
You can then query it in a few different fashions :
In a loop
for i in [0.1, 0.2]:
print(newvalue(i))
Or via list comprehension :
inputs = [0.1,0.2]
answers = [newvalue(i) for i in inputs]
print(answers)
In your first example simply replace the command
return value[0]
with
yield value[0]
Then you may use a newvalue() in these forms, for example:
list(newvalue()) to obtain a list of all calculated values,
for i in newvalue(): to iterate through calculated values.
Related
I was wondering, if I use some expression or function inside range(), will it calculate that expression every iteration or just the first time?
For instance, this:
l = len(some_array)
for i in range(l):
...
or
for i in range(len(some_array)):
...
is faster?
Also, is it the same for enumerate()?
The code range(len(some_array)) instanciates a range generator object, then it yields its values, the len is computed once and passed to the range
To iterate over a structure and have also the position, use enumarate, you have already the index and value available, and don't have to compute the length
for i, value in enumerate(some_array):
pass
I want to create a list of functions, each defined on the set {0,1,2}, by setting their values to those found in a list of values. To check what I did, I then print the values of my functions. Here are two attempts:
values_list = [[1,2,3],[4,5,6]]
function_list = []
function_list.append((lambda x: values_list[0][x]))
function_list.append((lambda x: values_list[1][x]))
print('Values of 1st function:',function_list[0](0),function_list[0](1),function_list[0](2))
print('Values of 1st function:',function_list[1](0),function_list[1](1),function_list[1](2))
function_list1 = []
for i in range(2):
function_list1.append((lambda x: values_list[i][x]))
print('Values of 1st function:',function_list1[0](0),function_list1[0](1),function_list1[0](2))
print('Values of 2nd function:',function_list1[1](0),function_list1[1](1),function_list1[1](2))
The first attempt works fine, of course, but in the second attempt, both functions in the list are identical. They both give back the second set of values.
Ok, so I guess the reason is, that the iterator that I used in the definition stopped at the second set of values. But in practice I will have huge lists of function values, of varying length, and I can't type a line for each function in my list, as in my first attempt. What could I do to solve this?
fix this line to:
function_list1.append((lambda x,y=i: values_list[y][x]))
I'm new to python and just starting to learn the basics.
I have defined a function recursively and I want to print a list of function outputs.
This is the code:
def x(n):
assert n>=0, "Only non-negative integers n are allowed"
if n == 0:
return 5
else:
return (x(n-1)+5)/x(n-1)
print([x(0),x(1),x(2)])
for k in range(0,9,1):
print(x(k))
So my question is: say I want to print a list of the first 10 outputs of the sequence/function, i.e. x(0),...,x(9), how do I do this without actually listing each output manually? I want them to be in the form "[x(0),...,x(9)]", just like I did for the first 3 values. My attempt is in the last command of the program, where k moves from 0 to 9. The last command clearly prints the first 10 outputs, but not as a list, i.e. in [] brackets.
Any input is greatly appreciated.
One Solution:
I replaced the code
for k in range(0,9,1):
print(x(k))
with
print([x(k) for k in range(9)])
This puts the outputs in a list, i.e. in the [ ] brackets. Worked wonderfully!
You can use list comprehension.
print([x(n) for n in range(9)])
# outputs: [5, 2.0, 3.5, 2.4285714285714284, 3.058823529411765, 2.634615384615384, 2.8978102189781025, 2.72544080604534, 2.83456561922366]
Explanation:
We're making a list out by calling the function x() for each of the numbers (n) that are in the range from 0 to 9 (not included).
Please note that it is implicit that the starting point of the range() function is 0, that the step is 1, and the endpoint (9) is not included.
Here's a solution for a beginner (not an one-liner, should be easier to understand):
myarray = []
for i in range(9):
myarray.append(x(i))
Just to show the alternative to a list comprehension using map, since this is practically the scenario that map was made for:
xs = map(x, range(9))
map takes a function, and applies it to each member of the supplied iterable.
The main difference between this and using a comprehension is this returns a lazy iterable (a map object), not a list. x will not be applied to an element until you request the element.
Use of a list comprehension/generator expression is preferable in the majority of scenarios, but map is nice if you need/can tolerate a lazy result, and you already have a predefined function.
I have first function which is not possible to modify or change! It displays value of the variable (main_index field which cannot be the list, tuple, dictionary etc. It is simple just a variable and must remain as it is)
That function triggers second function which can return multiple values so the idea is to somehow display those multiple values one by one, but not putting them into the list or dict. etc. Second function can be changed in any way.
Code is the following (please take into account that first function cannot be modified in any way, I am just simplifying it here).
def not_changeable():
value_to_check='7.1'
main_index=generate_index(value_to_check)
print (main_index)
def generate_index(index):
dictionary={'7.1.1':{'value':'1'},'7.1.2':{'value':'2'},'7.100.3':{'value':'3'}}
filtered_dict={}
concatanatedIndex=index+'.'
for k in dictionary.keys():
if concatanatedIndex in k:
filtered_dict[k]=dictionary[k]
print (filtered_dict)
for indx in filtered_dict:
return (filtered_dict.get(indx).get('value'))
not_changeable()
As output I am getting one value (because of return function which ends the script)
{'7.1.1': {'value': '1'}, '7.1.2': {'value': '2'}}
1
But I would like to get values
1
2
without any modification on the first function.
I am aware that if I return list I will be able to display all values, but is it possible to display 1 and 2 without modifications on the first function?
Returning in a for loop is often not what you want, it might be better to build the data structure in the loop and then return later, or return the whole data structure as it is being built in a comprehension. Here you can return a string with newline characters instead of a value, like this:
def generate_index(index):
dictionary={'7.1.1':{'value':'1'},'7.1.2':{'value':'2'},'7.100.3':{'value':'3'}}
filtered_dict={}
concatanatedIndex=index+'.'
for k in dictionary.keys():
if concatanatedIndex in k:
filtered_dict[k]=dictionary[k]
print (filtered_dict)
return '\n'.join(sorted(filtered_dict.get(indx).get('value') for indx in filtered_dict))
This will print
{'7.1.2': {'value': '2'}, '7.1.1': {'value': '1'}}
1
2
Breakdown of the last statement: '\n'.join(sorted(filtered_dict.get(indx).get('value') for indx in filtered_dict)):
We use a comprehension to generate the data we are interested in: filtered_dict.get(indx).get('value') for indx in filtered_dict - this is actually a generator comprehension, but you can put [] to make it a list comprehension.
Because we are iterating over a dictionary, and dictionaries not guaranteed to be in a certain order (though I believe this is changed with Python 3.6), I have added the sorted call to make sure 1 comes before 2.
To turn an iterable (like a list) into a string, we can use the string method .join(), which creates a string by joining together the elements in the list and puts the string in between each one. so '-hello-'.join(['a', 'b', 'c']) will become 'a-hello-b-hello-c'.
Actually a simpler way to build the return string would be to iterate over dict.values() instead of the actual dict. And if we are using python version > 3.6 we can skip the sorted call, so the return simply becomes: return '\n'.join(v.get('value') for v in filtered_dict.values()).
But a better design might be to return the values in a dictionary and print them in a specific format in a separate function that is only responsible for display.
You can adapt the generate_index function to return a generator, aka something you can iterate over (note the last line in the code below).
You can read up on generators here or see the documentation
dictionary={'7.1.1':{'value':'1'},'7.1.2':{'value':'2'},'7.100.3':{'value':'3'}}
filtered_dict={}
concatanatedIndex=index+'.'
for k in dictionary.keys():
if concatanatedIndex in k:
filtered_dict[k]=dictionary[k]
print (filtered_dict)
for indx in filtered_dict:
# change from return to yield here to create a generator
yield filtered_dict.get(indx).get('value')
Note that by calling this generate_index, you were already kind of shooting for a generator! Then you can call the result in your other function like so:
main_index=generate_index(value_to_check)
for index in main_index:
print(index)
Hope this does what you want
Trying to iterate over range of numbers (or list) to check if values are equal. Seems very simple, but I cant seem to find a way to do it.
I am trying to use an if statement to check scope of items in a 2D array.
# check if x is equal to var if added to any number between 0 and 10.
if var == x + any(range(10)): # not how it works, but how I want it to
# do something
After looking into any() I realize that It just returns True if any item in the iterate is True
Use any this way, also use generator:
if any(var==(x+i) for i in range(10)):
# do something
You have to use several Python functions for that:
if var in list(map(lambda item: x+item, range(10)))
list: Casts the parameter into a list object.
map: Applies a function (first parameter) to a collection of values (second parameter).
lambda: Lambda function.
You can also use this non-any version:
for i in range(10):
if var == (x+i):
break
Another way to do it using numpy:
import numpy as np
if var in x + np.arange(10) :
# do something
Would suffer from floating point problem if your numbers are not integers.