Store the output of a function into a variable - python

I have the following function that returns data:
def get_comments():
for i in data:
comment_data = i['comments']
for z in comment_data:
comments = comment_data['data']
for j in comments:
comment = j['message']
print(comment)
I would like to save the output of this function to a variable. I'm using print instead of return (in the function get_comments) since, return only returns the final row of my data. This is what i have tried to account for that:
def hypothetical(x):
return x
z = hypothetical(get_comments())
print(z)
However the output of the variable z is "None".
When i try some other value(i.e.):
z = hypothetical(5)
print(z)
z is equal to 5 of course.
Thanks

Instead of printing each line, you need to add it to a different data structure (such as a list) and return the whole list at the end of get_comments().
For example:
def get_comments():
to_return = []
for i in data:
comment_data = i['comments']
for z in comment_data:
comments = comment_data['data']
for j in comments:
comment = j['message']
to_return.append(comment)
return to_return
If you want to get a bit more advanced, you can instead create a generator using yield:
def get_comments():
for i in data:
comment_data = i['comments']
for z in comment_data:
comments = comment_data['data']
for j in comments:
comment = j['message']
yield comment
Then you can iterate over get_comments() and it will go back into the generator each time to get the next comment. Or you could simply cast the generator into a list with list(get_comments()) in order to get back to your desired list of comments.
Refer to this excellent answer for more about yield and generators.

Related

Python how to create sublists in a loop

I have a python question about the following code block.
The expected output is a sublist, containing the name that is entered into the list, turn it into a gmail account and add a username that only shows the first 4 letters of the input. I currently have this code:
def database(L):
result = []
for i in L:
username = i[0:4]
result.append(i + '#gmail.com')
result.append(username)
return result
accounts = database(['Bakerfield', 'Thomas'])
print(accounts)
I currently get the output
['Bakerfield#gmail.com', 'Bake' , 'Thomas#gmail.com', 'Thom']
But I would like the output:
[['Bakerfield#gmail.com', 'Bake'], ['Thomas#gmail.com', 'Thom']]
This is because i am not using sublists, and I am unsure how to divide this function loop into one that creates a sublist out of these accounts and essentially seperates these lists.
Thanks in advance!!
Just do one append, but with a list:
def database(L):
result = []
for i in L:
username = i[0:4]
result.append([i + '#gmail.com', username])
return result
Output as required.
Your only issue is which the result.append section. Take a look at this revised code:
def database(L):
result = []
for i in L:
username = i[0:4]
result.append([i + '#gmail.com'])
result.append([username])
return result
accounts = database(['Bakerfield', 'Thomas'])
print(accounts)
Notice that you just forgot a single pair of brackets when using the append() function, this should fix it permanently.
I would use a dataclass for this. also, only one append required after instantiation.
from dataclasses import dataclass
#dataclass
class UsrEmial:
email: str
naem: str
def database(L):
result = []
for i in L:
username = i[0:4]
e_obj_for_usr = UsrEmial(f'{i}#gmail.com', username)
result.append(e_obj_for_usr)
# not do:
# result.append(username)
# reasoning: `UsrEmial` object contains already this info.
# here not do (2) appends, instead using only one (1) as above:
# result.append(i + '#gmail.com')
# result.append(username)
# reasoning: two appends will add to list but at the same level,
# such that 1st and 2nd append result will be as siblings with
# all the others in a list.
return result
accounts = database(['Bakerfield', 'Thomas'])
print(accounts)
# OK
assert accounts[-1].naem == 'Thomas'[0:4]
Out:
[UsrEmial(email='Bakerfield#gmail.com', naem='Bake'), UsrEmial(email='Thomas#gmail.com', naem='Thom')]

Partition list of tuples based on a value within each tuple

I am trying to sort a set of data in to 2 separate lists, fulltime and parttime. But it doesn't seem to be working. Can somebody point to where I'm getting this wrong?
data = [(['Andrew'], ['FullTime'], [38]),
(['Fred'], ['PartTime'], [24]),
(['Chris'], ['FullTime'], [38])]
def sort(var1, datadump):
positionlist = []
for b in range(0, len(datadump)):
temp2 = datadump[b][1]
if (temp2 == var1):
positionlist.append(datadump[b])
return (positionlist)
FullTimeList = sort("FullTime", data)
PartTimeList = sort("PartTime", data)
print(FullTimeList)
print(PartTimeList)
This is solved by altering
if (temp2 == var1):
to
if (temp2[0] == var1):
This is because the elements within each tuple are lists holding a string, not the strings themselves.
This problem could also be solved using two list comprehensions:
FullTimeList = [x for x in data if x[1][0] == 'FullTime']
PartTimeList = [x for x in data if x[1][0] == 'PartTime']
Not an answer: just a suggestion. Learn how to use the python debugger.
python -m pdb <pythonscript.py>
In this case, set a breakpoint on line 9
b 9
Run the program
c
When it breaks, look at temp2
p temp2
It tells you
['FullTime']
Look at var1
p var1
It tells you
'FullTime'
And there is your problem.
You'll get a better understanding if you name your variables and functions with descriptive names:
data = [(['Andrew'], ['FullTime'], [38]),
(['Fred'], ['PartTime'], [24]),
(['Chris'], ['FullTime'], [38])]
def filter_records(value, records):
result = []
for i in range(len(records)): # i and j are usual variable names for indices (b is not)
record = records[i]
name, work, hours = record # give names to the parts
if work[0] == value: # work[0] since the values are lists (no need for parenthesis)
result.append(record)
return result # no need for parenthesis
FullTimeList = filter_records("FullTime", data)
PartTimeList = filter_records("PartTime", data)
the pattern:
for i in range(len(records)):
record = records[i]
is an anti-pattern in Python - meaning that there is a better way to write it:
for record in records:
...

List-Then-Eliminate implementation in Python

I'm trying to implement the List-Then-Eliminate algorithm using a dataset. However, I am getting the wrong vector space at the end. I am unable to figure out what the issue is.
Basically, I iterate through all the training instances. For each hypothesis, I use the last 5 bits to check if the training instance, x is the same and then compare the c(x)
Any assistance would be appreciated. Below is my code.
def gen_vector_space(k):
return [''.join(x) for x in itertools.product('01', repeat=k)]
#basically values from 0-65536 in binary
vector_space = gen_vector_space(pow(2,4))
for train_inst in train_data:
result = train_inst[-1]
d = train_inst[:-1]
for h in vector_space:
if h[-5:-1] == d:
if (h[-1] != result):
vector_space.remove(h)
print(len(vector_space))
I'd suggest an edit to the function that creates your vector space. Starting with your original function:
def create_space(k):
return [''.join(x) for x in itertools.product('01', repeat=k)]
When you call that function, you are completely iterating over that range to build the list, then iterating the list again to filter out values. Two approaches to fix that:
If statements in function
# Redefine your function to only return values that matter to you
def create_space(k, d, result):
"""
This will filter out your limits, takes result and d as params
"""
vector_space = []
for x in itertools.product('01', repeat=k):
if x[-5:-1]==d and x[-1]!= result:
vector_space.append(x)
return vector_space
# define k, d, and result here
vector_space = create_space(k, d, result)
Generator Approach
Or, the yield keyword will calculate values one at a time, so you are only iterating once:
def create_space(k):
for x in itertools.product('01', repeat=k):
yield x
vector_space = []
# define d and result here
for x in create_space(k):
if x[-5:-1]==d and x[-1]!= result:
vector_space.append(x)
The thing to note with either of these approaches is that I'm not editing an already established object while iterating over it. Instead, I've put the filtering on before the space is created, that way you get exactly what you want on the first go.

Anybody know how to use pyresttest's 'fixed_sequence' generator?

I'm trying to use pyresttest's benchmarking framework to generate a sequence of entries in my flask_sqlalchemy-based database. I would like to read input values from a pre-defined list as advertised by this framework's benchmarking generator type 'fixed_sequence', but it's only picking up the first element of the list.
Here is the issue that explains my problem in detail, with an example: https://github.com/svanoort/pyresttest/issues/264
Any pointer in the right direction will be greatly appreciated
I looked into the code, it is jsut a bug, this feature was never used by anyone.
https://github.com/svanoort/pyresttest/blob/master/pyresttest/generators.py#L100
instead of:
```
def factory_fixed_sequence(values):
""" Return a generator that runs through a list of values in order, looping after end """
def seq_generator():
my_list = list(values)
i = 0
while(True):
yield my_list[i]
if i == len(my_list):
i = 0
return seq_generator
It should be:
def factory_fixed_sequence(values):
""" Return a generator that runs through a list of values in order, looping after end """
def seq_generator():
my_list = list(values)
i = 0
while(True):
yield my_list[i]
i += 1
if i == len(my_list):
i = 0
return seq_generator
```
The i += 1 is missing

how to point towards a method given variable python

possibleRequests = ['test', 'test1']
def inboxReader():
global inbox
tempInbox = []
tempInbox = inbox.inboxMessage #inboxMesage remains filled?
print(inbox.inboxMessage, 'inboxReader')
i = 0
while (i < len(tempInbox)):
if (tempInbox[i] in possibleRequests):
print('THIS IS WORKING')
#print(i)
i+=1
I want to be able to have possible requests point towards a method to run rather than have a long list of if statments. What am I able to do in order to have a variable point towards and run a method.
Cheers,
Marc
You can first create a dictionary of functions then refer to it with tempInbox[i]. Example code below:
def func_a(x):
return x
def func_b(x):
return x*10
tempInbox = (2,3)
fn_dict = {"a":func_a,"b":func_b}
print fn_dict["a"](tempInbox[0]) # returns 2
print fn_dict["b"](tempInbox[1]) # returns 30

Categories