Expression or function as an argument of Range function - python

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

Related

Result of function vs loop

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.

How to print a list of function values from a generating function in python?

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.

How to write a function with a list as parameters

Here is the question, I'm trying to define a function sample_mean that takes in a list of numbers as a parameter and returns the sample mean of the the numbers in that list. Here is what I have so far, but I'm not sure it is totally right.
def sample_mean(list):
""" (list) -> number
takes in a list of numbers as a parameter and returns the sample mean of the the numbers in that list
sample_mean =
sample_mean =
"""
mean = 0
values = [list]
for list in values:
print('The sample mean of', values, 'is', mean(list))
Firstly, don't use list as a name because it shadows/hides the builtin list class for the scope in which it is declared. Use a name that describes the values in the list, in this case samples might be a good name. The function could be implemented with something like this:
def sample_mean(samples):
total = 0
for value in samples:
total = total + value
return total / float(len(samples))
Or a shorter version which avoids writing your own loop by making use of Python's sum() function :
def sample_mean(samples):
return sum(samples) / float(len(samples))
Call the function like this:
>>> print(sample_mean([1,2,3,4,5]))
3.0
Note the use of float() to ensure that the division operation does not lose the fractional part. This is only an issue in Python 2 which uses integer division by default. Alternatively you could add this to the top of your script:
from __future__ import division
If you are sure that you only need to support Python 3 you can remove the float() and ignore the above.
As stated above by #idjaw, don't use list as a parameter instead use listr (for example). Your values = [list] is erroneous (also stated by #idjaw) and should be removed.
Also, according to PEP257, you should not use "(list) -> number" in your docstrings as that should only be used for builtins.
Finally, your loop should look like for l in listr: and then you add values to your mean variable. divide it by the number of values in the list and print the result.

Keyword functions for Python min/max

I am trying to understand how this works:
my_dict = {'a':2,'b':1}
min(my_dict, key=my_dict.get)
produces
b
Which is a really cool feature and one I want to understand better.
Based on the documentation
min(iterable[, key])
Return the smallest item in an iterable or the smallest of two or more arguments...
The optional key argument specifies a one-argument ordering function like that used for list.sort(). The key argument, if supplied, must be in keyword form (for example, min(a,b,c,key=func)).
Where can I find out more about available functions? In the case of a dictionary, is it all the dictionary methods?
Edit: I came across this today:
max(enumerate(array_x), key=operator.itemgetter(1))
Still looking for information on available keyword functions for min/max
The code you have written is
my_dict = {'a':2,'b':1}
min(my_dict, key=my_dict.get)
actually this works on min function.
so, what does min do?
min(a, b, c, ...[, key=func]) -> value
With a single iterable argument, return its lowest item. With two or more arguments, return the lowest argument.
The key here is used to pass a custom comparison function.
Example: output max by length of list, where arg1, arg2 are both lists.
>>>> max([1,2,3,4], [3,4,5], key=len)
[1, 2, 3, 4]
But what if I want the max from the list, but by considering the second element of the tuple? here we can use functions, as given in official documentation. The def statements are compound statements they can't be used where an expression is required, that's why sometimes lambda's are used.
Note that lambda is equivalent to what you'd put in a return statement of a def. Thus, you can't use statements inside a lambda, only expressions are allowed.
>>> max(l, key = lambda i : i[1])
(1, 9)
# Or
>>> import operator
>>> max(l, key = operator.itemgetter(1))
(1, 9)
so the functions are basically depend upon the the iterable and and passing the criteria for the comparison.
Now in your example, you are iterating over your dictionary. And in key, you are using get method here.
The method get() returns a value for the given key. If key is not available then returns default value None.
As here, no arguments are there in get method it simply iterates over values of dictionary. And thus the min gives you the key having minimum value.
For max(enumerate(array_x), key=operator.itemgetter(1))
we want to compare the values of array instead of their indices. So we have enumerated the array.
enumerate(thing), where thing is either an iterator or a sequence, returns a iterator that will return (0, thing[0]), (1, thing1), (2, thing[2])
now we have used itemgetter function of operator module. operator.itemgetter(n) constructs a callable that assumes an iterable object (e.g. list, tuple, set) as input, and fetches the n-th element out of it.
you can also use lambda function of here like
max(enumerate(array_x), key=lambda i: i[1])
So the range of functions in key is almost up to the use. we can use many functions but the sole motive is , it is the criteria for that comparison.
Imagine you have objects with some attribute you want to use to get the minimum value:
min(my_objects, key=lambda x: x.something)
This will give you the object with the smallest something attribute.
The same thing exists for example in sorted() so you can easily sort by a value derived from the object. Imagine you have a list of people and want to sort by first name, then last name:
people.sort(key=lambda x: (x.first_name, x.last_name))

Don't understand this python For loop

I'm working through a tutorial which includes this code:
for position, target in population_gen(population):
pos = float(position)
all_inputs.append([random.random(), pos * factor])
all_targets.append([target])
I don't fully understand how the for loop works. In particular: what is the loop iterating through exactly? I'm only familiar with simple examples like for i in mylist:. How can there be a function call on the right-hand side of in, and two things separated by a comma on the left-hand side?
The function population_gen is returning a list of tuples, which are unpacked automatically into variable names using this syntax.
So basically, you're getting something like the following as return value from the function:
[("pos1", "target1"), ("pos2", "target2"), ]
Given this example, in the the for loop's first iteration, the variables "position" and "target" will have the values:
position = "pos1"
target = "target1"
In second iteration:
position = "pos2"
target = "target2"
Tuple unpacking.
for a, b in [(1, 2), (3, 4)]:
print a
print b
print 'next!'
And the function is just a function.
The function either returns a sequence or serves as something called a "generator:" it spits out successive elements in a sequence for the caller to iterate through. This question concerning the yield keyword has some thorough discussion of how these work.
As for the comma, since the function (apparently) returns a two-tuple, the comma-separated list of names is a convenient way to name individual elements of the tuple without having to unpack them yourself.
It's called tuple unpacking. The population_gen (generator) function yields tuples containing exactly two elements. In python, you can assign several variables to tuples like this
a, b = (1, 2)
So in this for loop, you directly put the two tuple values from the current iteration item into your two variables position and target.

Categories