How to iterate over a list in if conditionals? - python

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.

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.

Python sum(generator): calling an external function

take the code:
SUM = sum(x() for x in xs)
I am writing some code that is in need of calling another function before each x() such that x() will compute the right value
is the only way to do this like so?
for x in xs: x.pre()
SUM = sum(x() for x in xs)
or
SUM = 0
for x in xs:
x.pre()
SUM += x()
incorporating x.pre into x is obviously possible but would make the real code exceptionally ugly and hard to read. is there some way of using generator expressions I am unaware of that would allow what I am trying to achieve?
eg:
SUM = sum(x(), x.pre() for x in xs)
thats obviously just an non-summable tuple generator
I would simply use the for-loop you already presented.
There are ways to do what you want in other ways. For example you could use functools.reduce with a customized function here instead of sum :
def pre_then_add(accumulated, new_one):
new_one.pre() # do some stuff so we get the right value
return accumulated + new_one() # add the value to the accumulated sum
and then it's just a matter of calling reduce:
import functools
functools.reduce(pre_then_add, xs, 0)
Note that this requires to give a "base value" otherwise the function is too simple but also that reduce with a customized function is not necessarily the most efficient or elegant way.
As pointed in the comments (thanks to #SteveJessop) another possibility using sum would be:
def pre_then_call(x):
x.pre();
return x()
sum(pre_then_call(x) for x in xs)
But just to repeat it: I would use the explicit loop. Those are far easier to understand in terms of what you are doing and why.

function parameter taken from a list

So i have a function which takes multiple values:
def kgV(a,b, *rest):
#the function itself doesnt matter for the question
#beside that it returns an int no matter how many arguments where passed
now i have a list or range():
# for example
myRange = range(2, 10)
myList = [2,9,15]
Now i want it to possible to give my Function the list or range as parameter so that it works as if i had given the every int of the range or list as parameter.
#how can i make this work?
kgV(myRange)
kgV(myList)
i tried some things like: for i in a etc
but they all returned errors :-/
edit: i just solved it using a help function but it seems a very un pythonic way of doing it, so is there a more pythonic / generic way of doing it?
def kgVList(liste):
result = liste[0]
for i in liste:
result = kgV(i, result)
return result
You can simply unpack the values like this:
kgV(*a)

Check if item is in an array / list [duplicate]

This question already has answers here:
Is there a short contains function for lists?
(6 answers)
Closed last month.
If I've got an array of strings, can I check to see if a string is in the array without doing a for loop? Specifically, I'm looking for a way to do it within an if statement, so something like this:
if [check that item is in array]:
Assuming you mean "list" where you say "array", you can do
if item in my_list:
# whatever
This works for any collection, not just for lists. For dictionaries, it checks whether the given key is present in the dictionary.
I'm also going to assume that you mean "list" when you say "array." Sven Marnach's solution is good. If you are going to be doing repeated checks on the list, then it might be worth converting it to a set or frozenset, which can be faster for each check. Assuming your list of strs is called subjects:
subject_set = frozenset(subjects)
if query in subject_set:
# whatever
Use a lambda function.
Let's say you have an array:
nums = [0,1,5]
Check whether 5 is in nums in Python 3.X:
(len(list(filter (lambda x : x == 5, nums))) > 0)
Check whether 5 is in nums in Python 2.7:
(len(filter (lambda x : x == 5, nums)) > 0)
This solution is more robust. You can now check whether any number satisfying a certain condition is in your array nums.
For example, check whether any number that is greater than or equal to 5 exists in nums:
(len(filter (lambda x : x >= 5, nums)) > 0)
You have to use .values for arrays.
for example say you have dataframe which has a column name ie, test['Name'], you can do
if name in test['Name'].values :
print(name)
for a normal list you dont have to use .values
You can also use the same syntax for an array. For example, searching within a Pandas series:
ser = pd.Series(['some', 'strings', 'to', 'query'])
if item in ser.values:
# do stuff

Categories