Substitution in function based on input parameter - python

Say I have multiple lists called data_w1, data_w2, data_w3, ..., data_wn. I have a function that takes an integer band as an input, and I'd like the function to operate only on the corresponding list.
I am familiar with string substitution, but I'm not dealing with strings here, so how would I do this? Some pseudocode:
def my_function(band):
wband_new = []
for entry in data_wband:
# do stuff
wband_new.append( #new stuff )
return wband_new
But doing the above doesn't work as expected because I get the errors that anything with wband in it isn't defined. How can I do this?

Not exactly sure what you're asking, but if you mean to have lists 1, 2, ..., n then an integer i and you want to get the i'th list, simply have a list of lists and index the outer list with the integer i (in your case called band).
l = [data_w1, data_w2, data_w3]
list_to_operate_on = l[band]
func(list_to_operate_on)

Suppose you have your data variables in the script before the function. What you need to do is substitute data_wband with globals()['data_w'+str(band)]:
data_w1 = [1,2,3]
data_w2 = [4,5,6]
def my_function(band):
wband_new = []
for entry in globals()['data_w'+str(band)]:
# do stuff
wband_new.append( #new stuff )
return wband_new

Related

How to create lists given a number without writing everything line by line?

Say there is a variable that finds a number of objects, and empty lists have to be created for each object.
For example:
objectNum = 4
a = [ ]
b = [ ]
c = [ ]
d = [ ]
Or with any other number, and those lists have to be named by alphabet. How can this be done?
I tried using globals() function, but that was applicable to variables, not lists
When you want a variable number of variables that you don't know in advance, one usually uses a dictionary instead of adding them dynamically to the module namespace as a variable. If you didn't know you were going to add, say, "t", how would you know to use it later?
In your example, you want lower case letters up to some given value to reference lists. You could build a dict
import string
objectNum = 4
assert objectNum <= 26
data = {}
for i in range(objectNum):
data[string.ascii_lower[i]] = []
# or more likey you'd write it...
data = {var:[] for var in string.ascii_lower[:objectNum]}
Now, instead of variable a, you have data["a"]. That seems like more typing in this example, but the idea is autogeneration.

How to store multiple results from a function in a for loop as unique variables in Python?

I have a function that returns different values based on different inputs.
I want it to go through a list, spitting out results for each input. But then I don't know how to store each of those results as a unique variable...
Here's an example of the list
list = ["input1", "input2", "input3"]
The function returns a different integer depending on the input.
I'm going through the list with a for loop like so
for input in list:
my_function(input)
The function in the loop runs for each item in the list and returns a unique integer for each. But how do I store each of the returned values as their own variable?
I've tried this. But it overwrites the variable each time and only leaves me with the last one in the loop
for input in list:
var = my_function(input)
Is there some way to dynamically change that variable in each run through the loop?
vars = []
for input in list:
vars.append(my_function(input))
or
vars = [my_function(input) for input in list]
or the dictionary approach
vars = {}
for input in list:
vars[input] = my_function(input)
or the inline
vars = {input: my_function(input) for input in list}
I'd like to know why you're trying to achieve what you're trying to achieve, it sounds like a terrible idea, what you want seems to be another list or dictionary.
With that being said, I wouldn't recommend it but this snippet of code might do the trick.
ctr = 0
def my_function(inp):
return f"RETURN VAL OF MY FUNCTION FOR INPUT {inp}"
lst = ["input1", "input2", "input3"]
for i in lst:
exec(f'var{ctr+1} = "{my_function(i)}"')
ctr+=1
print(var1)
print(var2)
l1 is a list that stores all inputs every time you call your function until the loop stops
l1 = []
for input in list:
l1.append(my_function(input))

Dataquest: I've just learned how to define a function in python. Now I want to run it in a loop.

I am a python beginner and I learn using dataquest.
I want to use a self-defined function in a loop to check every item in a list, whether it is a color movie or not and add the results (True, False) to a list. Right now the function returns False only, also way to many times. Any hints what I did wrong?
wonder_woman = ['Wonder Woman','Patty Jenkins','Color',141,'Gal Gadot','English','USA',2017]
def is_usa(input_lst):
if input_lst[6] == "USA":
return True
else:
return False
def index_equals_str(input_lst, index, input_str):
if input_lst[index] == input_str:
return True
else:
return False
wonder_woman_in_color = index_equals_str(input_str="Color", index=2, input_lst=wonder_woman)
# End of dataquest challenge
# My own try to use the function in a loop and add the results to a list
f = open("movie_metadata.csv", "r")
data = f.read()
rows = data.split("\n")
aufbereitet = []
for row in rows:
einmalig = row.split(",")
aufbereitet.append(einmalig)
# print(aufbereitet)
finale_liste = []
for item in aufbereitet:
test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)
finale_liste.append(test)
print(finale_liste)
Also at pastebin: https://pastebin.com/AESjdirL
I appreciate your help!
The problem is in this line
test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)
The input_lst argument should be input_lst=item. Right now you are passing the whole list of lists to your function everytime.
The .csv file is not provided but I assume the reading is correct and it returns a list like the one you provided in the first line of your code; in particular, that you are trying to pack the data in a list of lists (the einmalig variable is a list obtained by the row of the csv file, then you append each einmalig you find in another list, aufbereitet).
The problem is not in the function itself but in the parameters you give as inputs: when you do
test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)
you should see that the third parameter is not a list corresponding to the single movie data but the whole list of movies. This means that the Python interpreter, in the function, does this iteration for every item in aufbereitet (that is, iterates for n times where n is aufbereitet's length):
if aufbereitet[2] == "Color":
return True
else:
return False
It is clear that even if the movie is in color, the comparison between a list (an element of aufbereitet) and a string returns False by default since they are different types.
To correct the issue just change the line
test = index_equals_str(input_str="Color", index=2, input_lst=aufbereitet)
with
test = index_equals_str(input_str="Color", index=2, input_lst=item)
since, when you use the for loop in that way, the variable item changes at each iteration with the elements in aufbereitet.
Notice that if you're learning that's still ok to use functions but you can use an inline version of the algorithm (that's what Python is famous for). Using
finale_liste = [item[2] == "Color" for item in aufbereitet]
you obtain the list without going to define a function and without using the for loop. That's called list comprehension.
Another thing you can do to make the code more Pythonic - if you want to use the functions anyway - is to do something like
def index_equals_str(input_lst, index, input_str):
return input_lst[index] == input_str
that has the same result with less lines.
Functional programming is sometimes more readable and adaptable for such tasks:
from functools import partial
def index_equals_str(input_lst, index=1, input_str='Null'):
return input_lst[index] == input_str
input_data = [['Name1', 'Category1', 'Color', 'Language1'],
['Name2', 'Category2', 'BW', 'Language2']]
result = list(map(partial(index_equals_str, input_str='Color', index=2), input_data))
# output
# [True, False]

How do I use a for loop to store function output in separate variables?

Suppose I have the following function:
def function3(start, end):
"""Read MO information."""
config_found = False
var = []
for line in v['molecular orbital primitive coefficients']:
if line.strip() == end:
config_found = False
elif config_found:
i = line.rstrip()
var.append(i)
elif line.strip() == start:
config_found = True
var1 = [elem.strip() for elem in var]
var2 = var1[1:-1]
var3 = np.array([line.split() for line in var2])
var3 = np.asarray([list(map(float, item)) for item in var3])
return var3
And suppose I store its output in variables like so:
monumber1=function3('1','2')
monumber2=function3('2','3')
monumber3=function3('3','4')
etc.
Is there a way for me to execute this function a set number of times and store the output in a set number of variables without manually setting the variable name and function arguments every time? Maybe using a for loop? This is my attempt, but I'm struggling to make it functional:
for i in xrange(70):
monumber[x] = function3([i],[i+1])
Thank you!
The problem is your use of square brackets. Here is code that should work:
monumber = [] # make it an empty list
for i in xrange(70):
monumber.append(function3(str(i),str(i+1))) # you had string integers, so cast
For the more Pythonic one-liner, you can use a list comprehension:
monumber = [function3(str(i),str(i+1)) for i in xrange(70)]
Now that the monumber variable has been created, I can access the element at any given index i using the syntax monumber[i]. Some examples:
first = monumber[0] # gets the first element of monumber
last = monumber[-1] # gets the last index of monumber
for i in xrange(10,20): # starts at i = 10 and ends at i = 19
print(monumber[i]) # print the i-th element of monumber
You've almost got it. Except you should use i on the left hand side, too:
monumber[i] = function3([i],[i+1])
Now, this is the basic idea, but the code will only work if monumber is already a list with enough elements, otherwise an IndexError will occur.
Instead of creating a list and filling it with placeholders in advance, we can dynamically append new values to it:
monumber = []
for i in xrange(70):
monumber.append(function3([i],[i+1]))
Another problem is that you seem to be confusing different types of arguments that your function works with. In the function body, it looks like start and end are strings, but in your code, you give to lists with one integer each. Without changing the function, you can do:
monumber = []
for i in xrange(70):
monumber.append(function3(str(i),str(i+1)))

Choose list which is returned by def

I have a definition to separate some coordinates on specific properties.
For this separation I use 1 definition and within the definition i have 9 lists (different criteria's). Now for the output i just want the list defined by me. Otherwise I cannot use it for plotting.
def sorteerCord(cord):
tweestijging=[]
stijginggelijk=[]
stijgingdaling=[]
tweedaling=[]
dalinggelijk=[]
dalingstijging=[]
tweegelijk=[]
gelijkstijging=[]
gelijkdaling=[]
y=0
while y<len(cord):
lijst=cord[y]
if (lijst[1]-lijst[0])>0.5:
if (lijst[2]-lijst[1])>0.5:
tweestijging.append(y)
if (lijst[2]-lijst[1])<=0.5 and (lijst[2]-lijst[1])>=-0.5:
stijginggelijk.append(y)
if (lijst[2]-lijst[1])<-0.5:
stijgingdaling.append(y)
if (lijst[1]-lijst[0])<-0.5:
if (lijst[2]-lijst[1])>0.5:
dalingstijging.append(y)
if (lijst[2]-lijst[1])<=0.5 and (lijst[2]-lijst[1])>=-0.5:
dalinggelijk.append(y)
if (lijst[2]-lijst[1])<-0.5:
tweedaling.append(y)
if (lijst[1]-lijst[0])<=0.5 and (lijst[1]-lijst[0])>=-0.5:
if (lijst[2]-lijst[1])>0.5:
gelijkstijging.append(y)
if (lijst[2]-lijst[1])<=0.5 and (lijst[2]-lijst[1])>=-0.5:
tweegelijk.append(y)
if (lijst[2]-lijst[1])<-0.5:
gelijkdaling.append(y)
y=y+1
print raw_input()
return raw_input()
Is their a way to define in my def what the output file is like (def sorteerdCord(cord,outpu=tweestijging)
I am guessing that in the last two lines you want the user to input what output list to use but am not quite sure. You could use dictionary to map input strings to variables.
Something like:
def sorteerCord(cord, output):
# all of your separation code
outputmap = { 'tweestijging': tweestijging,
'gelijkstijging' : gelijkstijging,
# and more of those
}
return outputmap[ output ]
And then call:
sorteerCord(cord, 'gelijkstijging')
You could of course also opt for returning all of the lists or keep them in a dictionary instead:
output = { 'tweestijging': [],
'gelijkstijging': [],
# etc
}
# code to manipulate lists goes here
return output
Then selecting one afterwards using the same technique.

Categories