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')]
Related
So, I would like to convert my string input
'f(g,h(a,b),a,b(g,h))'
into the following list
['f',['g','h',['a','b'],'a','b',['g','h']]]
Essentially, I would like to replace all '(' into [ and all ')' into ].
I have unsuccessfully tried to do this recursively. I thought I would iterate through all the variables through my word and then when I hit a '(' I would create a new list and start extending the values into that newest list. If I hit a ')', I would stop extending the values into the newest list and append the newest list to the closest outer list. But I am very new to recursion, so I am struggling to think of how to do it
word='f(a,f(a))'
empty=[]
def newlist(word):
listy=[]
for i, letter in enumerate(word):
if letter=='(':
return newlist([word[i+1:]])
if letter==')':
listy.append(newlist)
else:
listy.extend(letter)
return empty.append(listy)
Assuming your input is something like this:
a = 'f,(g,h,(a,b),a,b,(g,h))'
We start by splitting it into primitive parts ("tokens"). Since your tokens are always a single symbol, this is rather easy:
tokens = list(a)
Now we need two functions to work with the list of tokens: next_token tells us which token we're about to process and pop_token marks a token as processed and removes it from the list:
def next_token():
return tokens[0] if tokens else None
def pop_token():
tokens.pop(0)
Your input consist of "items", separated by a comma. Schematically, it can be expressed as
items = item ( ',' item )*
In the python code, we first read one item and then keep reading further items while the next token is a comma:
def items():
result = [item()]
while next_token() == ',':
pop_token()
result.append(item())
return result
An "item" is either a sublist in parentheses or a letter:
def item():
return sublist() or letter()
To read a sublist, we check if the token is a '(', the use items above the read the content and finally check for the ')' and panic if it is not there:
def sublist():
if next_token() == '(':
pop_token()
result = items()
if next_token() == ')':
pop_token()
return result
raise SyntaxError()
letter simply returns the next token. You might want to add some checks here to make sure it's indeed a letter:
def letter():
result = next_token()
pop_token()
return result
You can organize the above code like this: have one function parse that accepts a string and returns a list and put all functions above inside this function:
def parse(input_string):
def items():
...
def sublist():
...
...etc
tokens = list(input_string)
return items()
Quite an interesting question, and one I originally misinterpreted. But now this solution works accordingly. Note that I have used list concatenation + operator for this solution (which you usually want to avoid) so feel free to improve upon it however you see fit.
Good luck, and I hope this helps!
# set some global values, I prefer to keep it
# as a set incase you need to add functionality
# eg if you also want {{a},b} or [ab<c>ed] to work
OPEN_PARENTHESIS = set(["("])
CLOSE_PARENTHESIS = set([")"])
SPACER = set([","])
def recursive_solution(input_str, index):
# base case A: when index exceeds or equals len(input_str)
if index >= len(input_str):
return [], index
char = input_str[index]
# base case B: when we reach a closed parenthesis stop this level of recursive depth
if char in CLOSE_PARENTHESIS:
return [], index
# do the next recursion, return it's value and the index it stops at
recur_val, recur_stop_i = recursive_solution(input_str, index + 1)
# with an open parenthesis, we want to continue the recursion after it's associated
# closed parenthesis. and also the recur_val should be within a new dimension of the list
if char in OPEN_PARENTHESIS:
continued_recur_val, continued_recur_stop_i = recursive_solution(input_str, recur_stop_i + 1)
return [recur_val] + continued_recur_val, continued_recur_stop_i
# for spacers eg "," we just ignore it
if char in SPACER:
return recur_val, recur_stop_i
# and finally with normal characters, we just extent it
return [char] + recur_val, recur_stop_i
You can get the expected answer using the following code but it's still in string format and not a list.
import re
a='(f(g,h(a,b),a,b(g,h))'
ans=[]
sub=''
def rec(i,sub):
if i>=len(a):
return sub
if a[i]=='(':
if i==0:
sub=rec(i+1,sub+'[')
else:
sub=rec(i+1,sub+',[')
elif a[i]==')':
sub=rec(i+1,sub+']')
else:
sub=rec(i+1,sub+a[i])
return sub
b=rec(0,'')
print(b)
b=re.sub(r"([a-z]+)", r"'\1'", b)
print(b,type(b))
Output
[f,[g,h,[a,b],a,b,[g,h]]
['f',['g','h',['a','b'],'a','b',['g','h']] <class 'str'>
So I wrote this code to return back every string in the given lst: list once. Here is my code
def make_unique(lst: list[str]):
s = []
for x in lst:
if lst.count(x) == 1:
s.append(x)
else:
return(x)
return s
When I put in the input:
print(make_unique(lst=['row','mun','row']))
The output returns
row
but I want my output to return
['row','mun']
which is basically all the strings in the list printed once.
How can I do this??
Why not you try this one line short code to remove duplicates from your list and make it unique
def make_unique(lst):
return list(dict.fromkeys(lst))
print(make_unique(['row','mun','row'])) #['row','mun']
Easy way to do this is turn the list into a set. A set only shows each item once and thats what you want.
lst=['row','mun','row']
setLst = set(lst)
for elem in setLst:
print(elem)
You can use set.
lst=['row','mun','row']
print(set(lst))
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.
so I have a class with a list, and I would like to add a number to all the elements of that list, but not to every list in the class. I tried this:
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
data = [0]*len(list1)
for i,(l1,l2) in enumerate(zip(list1,list2)):
data[i] = class_name(l1,l2)
[(x + 5.0).list_name for x in data]
and it gives me the error:
TypeError: unsupported operand type(s) for +: 'instance' and 'float'
edit: people seem to not understand what I want. In the real code I have, the lists have been added to a class (in this case data) which I've been working with, but one of the lists in the class (specifically referring to magnitudes) needs to be calibrated. I do this by adding a number to every element in that list to calibrate it. This has to be done to the list connected to the class it's in, so I can't edit the list before putting it into the class.
I already have this class created much earlier in my code, and I needed it to be the way it was before so that I could work with all the elements. Now, later in the code, I want to calibrate this magnitude list within the class. Is there a way to do that?
maybe this attempt better illustrates what I'm trying to do:
[x.list_name for x in data] = [x.list_name+5 for x in data]
this also doesn't work, I get this error:
SyntaxError: can't assign to list comprehension
I just feel like it makes people understand what I need.
Check out the Map function for python.
https://docs.python.org/2/tutorial/datastructures.html#functional-programming-tools
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
def add_five(x): return x+5
list1 = map(add_five, list1)
#or instead you can use a lambda
list1 = map(lambda x: x+5 , list1)
EDIT: maybe try this.
for class_name in class_names:
class_name.list_name = map(lambda x: x+5 , class_name.list_name)
If you want to increment one of two lists stored as a list of pairs, this should work:
[x.list_name+5.0 for x in class_names]
x isn't a number, it's the class_name object. You want to retrieve the thing you want to increment from x (x.list_name) and then add 5.0.
You are adding the value to the instance first then accessing the attribute.
class class_name:
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
list1 = [1.0,2.0,3.0,4.0]
list2 = [4.0,5.0,6.0,7.0]
class_names = [0]*len(list1)
for i,(l1,l2) in enumerate(zip(list1,list2)):
class_names[i] = class_name(l1,l2)
print [x.list_name+5.0 for x in class_names]
I am not sure what you mean, but I have created a simple example:
class class_name(object):
def __init__(self,list_name,other_list):
self.list_name = list_name
self.other_list = other_list
self.list1 = []
self.list2 = []
self.list1.append(self.list_name)
self.list2.append(self.other_list)
print "My List1: ", self.list1
print "My List2: ", self.list2
def input_data():
list_one = raw_input("Data for list 1: ")
list_two = raw_input("Data for list 2: ")
class_name(list_one, list_two)
if __name__ == '__main__':
input_data()
Is that what you want to?
So I am trying to get a grasp on Hash Functions and how exactly they work. I have the following code but I keep getting an error when I try and run the code.
import sys
def part_one():
foo = open('input_table.txt')
for line in foo:
id, make, model, year = line.split(",")
print(make, model)
tuple_list = (make+model,)
return tuple_list
def hash_one(num_buffers, tuple_list):
#part_one()
# A being the first constant prime number to multiply by
# B being the prime number that we add to A*sum_of_chars
tuple_list = part_one()
A = 3
B = 5
count = 0
for item in tuple_list:
for char in item:
# sum_of_chars is the total of each letter in the word
count = ord(char)
count = count + tuple_list
index = ((A * sum_of_chars + B)) % num_buffers
return index
if __name__ == '__main__':
input_table = sys.argv[1]
num_buffers = int(sys.argv[2])
chars_per_buffer = int(sys.argv[3])
sys.argv[4] = 'make'
sys.argv[5] = 'model'
lst = []
for item in range(4, len(sys.argv)):
lst.append(sys.argv[item])
print(lst)
hash_one(lst)
What is wrong with my code that is causing the error? Can anyone help me?
1
You're calling hash() with no arguments, you have to hash something.
A hash of a number will just return the same number though, so it's not very interesting. It's for hashing things like strings.
2
part_one returns nothing, therefore when you call tuple_list = part_one(), it's value is set to None, and you can't iterate though it.
3
Passing in a list through an argument then overwriting it doesn't make any sense anyway. If you want to return a list then use a return statement.
4
It's odd to set argument variables in code, they're for reading things from the command line.
5
(Not an error, but...)
You can use a slice (lst = sys.argv[4:]) as an easier way to get a sub-section of a list.