Python 2D array with same values - python
I am a beginner programmer and I am doing a task for school. The task is to assign 4 constant variables and then use a code to work out the value. Each value has a corresponding letter and the program is asking the user to type in 5 numbers then the program will return the word. The code is the following:
array = [["L","N"], #define the 2d array, L=Letters, N=Numbers
["-","-"]] #line for space
a = 2#define the variables
b = 1
c = 7
d = 4
e = (a*b)+b#calcualtions
f = c+b
g = (d/a)-b
h = c*a
i = a+b+d
j = c-a
k = c-d*f
l = c+a
m = (c*a)-b
n = a*d
o = a+d-b
p = (c*d)-a*(b+d)
q = a*(c+(d-b))
r = (d*d)-b
s = r-f-g
array.append(["e",e])
array.append(["f",f])
array.append(["g",g])#append all the calculations
array.append(["h",h])
array.append(["i",i])
array.append(["j",j])
array.append(["k",k])
array.append(["l",l])
array.append(["m",m])
array.append(["n",n])
array.append(["o",o])
array.append(["p",p])
array.append(["q",q])
array.append(["r",r])
array.append(["s",s])
def answer():
len_row = len(array)
number_input = int(input("Enter number: "))
for i in range(len_row):
if number_input == (array[i][1]):
return array[i][0]
break
one_let = answer()
two_let = answer()
thr_let = answer()
fou_let = answer()
fiv_let = answer()
print(one_let,two_let,thr_let,fou_let,fiv_let)
The numbers that I am meant to put in are 6, 18,, 7, 8, and 3.
The word that prints is "spife" and the word that is meant to be printed is "spine". The problem is that there are two letters that have a variable of 8 and Python gets the first one only. Is there a way to print out the two seperate words but first with the first variable in a 2D array and second with the second 2D array? i.e spife then spine
Thank you for your help ahead, I am just a beginner! :)
Yes you can do it but is a bit tricky the secret is to use itertools.product on the list of letters that could have each of the five values.
First you need to use a better data structure such as a dict, (in this case a collection.defaltdict) to hold the letters that have some value. You can do this way:
import collections
import itertools
a = 2#define the variables
b = 1
c = 7
d = 4
e = (a*b)+b#calcualtions
f = c+b
g = (d/a)-b
h = c*a
i = a+b+d
j = c-a
k = c-d*f
l = c+a
m = (c*a)-b
n = a*d
o = a+d-b
p = (c*d)-a*(b+d)
q = a*(c+(d-b))
r = (d*d)-b
s = r-f-g
dat = collections.defaultdict(list)
for c in "abcdefghijklmnopqrs":
dat[eval(c)].append(c)
Now in dat you have a list of letters that match some number, for example
print(dat[6])
print(dat[18])
print(dat[7])
print(dat[8])
print(dat[3])
Outputs:
['s']
['p']
['i']
['f', 'n']
['e']
OK, then you need to change answerto return a list of letters, and collect the user input:
def answer():
number_input = int(input("Enter number: "))
return dat[number_input]
letts = [answer() for _ in range(5)] #collect five answers of the user
And the final magic is done here:
for s in map(lambda x: "".join(x),itertools.product(*letts)):
print(s)
Now if you are confused then study:
collections
collections.defaultdict
itertools
itertools.product
str.join
Related
Change each letter of the sentence/word to something specific
I would like to replace each letter of the sentence entered by the user with something specific. I tried it with the "replace" function, but the code is way too long, because I don't know how to make lowercase and uppercase letters in one, so the code doesn't get too long. Furthermore, I want a "+" sign between the new letters, but not at the beginning and end a = 'new_a' b = 'new_b' c = 'new_c' d = 'new_d' e = 'new_e' f = 'new_f' g = 'new_g' h = 'new_h' i = 'new_i' j = 'new_j' k = 'new_k' l = 'new_l' m = 'new_m' n = 'new_n' o = 'new_o' p = 'new_p' q = 'new_q' r = 'new_r' s = 'new_s' t = 'new_t' u = 'new_u' v = 'new_v' w = 'new_w' x = 'new_x' y = 'new_y' z = 'new_z' input_string = input("Text: ") new_string = input_string.replace('a', a).replace('b', b).replace('c', c).replace('d', d).replace('e', e)... print(new_string)
You can use a regular expression replacement with a callback function that looks up the replacements in a dictionary. import re replacements = {'a': 'new_a', 'b': 'new_b', ..., 'A': 'new_A', 'B': 'new_B', ...} new_string = re.sub('[a-z]', lambda match: replacements[match.group()], input_string) Note that your code has other problems besides being repetitive. If the input string is abc the replacement of a, b, and c will produce new_anew_bnew_c Then the replacement of e will produce nnew_ew_annew_ew_bnnew_ew_c and when it gets to n it will become new_nnew_new_ew_anew_nnew_new_ew_bnew_nnew_new_ew_c and the final result after replacing the w will be: nenew_w_nnenew_w_nenew_w_enew_w_anenew_w_nnenew_w_nenew_w_enew_w_bnenew_w_nnenew_w_nenew_w_enew_w_c
For all sets in a list, extract the first number only
I have a list that looks like this: b = [{'dg_12.942_ch_293','dg_22.38_ca_627'}, {'dg_12.651_cd_286','dg_14.293_ce_334'}, {'dg_17.42_cr_432','dg_18.064_cm_461','dg_18.85_cn_474','dg_20.975_cf_489'}] I want to keep only the first number for each item in each set: b = [{'12','22'}, {'12','14'}, {'17','18','18','20'}] I then want to find the difference between the smallest and the largest number of each set and put it in a list, so in this case I would have: b = [3,2,3]
Ugly and without any sanity check, but do the work. import re SEARCH_NUMBER_REGEX = re.compile("(\d+)") def foo(dataset): out = [] for entries in dataset: numbers = [] for entry in entries: # Search for the first number in the str n = SEARCH_NUMBER_REGEX.search(entry).group(1) n = int(n) numbers.append(n) # Sort the numbers and sustract the last one (largest) # by the first one (smallest) numbers.sort() out.append(numbers[-1] - numbers[0]) return out b = [ {'dg_12.942_ch_293', 'dg_22.38_ca_627'}, {'dg_12.651_cd_286', 'dg_14.293_ce_334'}, {'dg_17.42_cr_432', 'dg_18.064_cm_461', 'dg_18.85_cn_474', 'dg_20.975_cf_489'} ] print(b) # > [10, 2, 3]
This is giving o/p as [10,2,3] (The difference b/w 22 and 12 is 10) b = [{'12','22'}, {'12','14'}, {'17','18','18','20'}] l = [] for i in b: large ,small = -99, 99 for j in i: j = int(j) if large < j: large = j if small >j: small = j l.append(large - small) print(l)
Here's yet another way to do it: import re ba = [{'dg_12.942_ch_293', 'dg_22.38_ca_627'}, {'dg_12.651_cd_286', 'dg_14.293_ce_334'}, {'dg_17.42_cr_432', 'dg_18.064_cm_461', 'dg_18.85_cn_474', 'dg_20.975_cf_489'}] bb = [] for s in ba: ns = sorted([int(re.search(r'(\d+)', ss)[0]) for ss in s]) bb.append(ns[-1]-ns[0]) print(bb) Output: [10, 2, 3] Or, if you want to be ridiculous: ba = [{'dg_12.942_ch_293', 'dg_22.38_ca_627'}, {'dg_12.651_cd_286', 'dg_14.293_ce_334'}, {'dg_17.42_cr_432', 'dg_18.064_cm_461', 'dg_18.85_cn_474', 'dg_20.975_cf_489'}] bb = [(n := sorted([int(re.search(r'(\d+)', ss)[0]) for ss in s]))[-1]-n[0] for s in ba] print(bb)
In your final product I see it was "[3,2,3]" but if I am understanding your question correct, it would be [10,2,3]. Either way the code I have below will atleast point you in the right direction (hopefully). This code will iterate through each tuple in the list and split the str (since that is all we want to compare) and add them into lists. These numbers are then evaluated and subtracts the smallest number from the biggest number, and places it in a separate array. This "separate array" is the final one as shown in your question. Goodluck - hopefully this helps! import re b = [('dg_12.942_ch_293','dg_22.38_ca_627'), ('dg_12.651_cd_286','dg_14.293_ce_334'), ('dg_17.42_cr_432','dg_18.064_cm_461','dg_18.85_cn_474','dg_20.975_cf_489')] final_array = [] for tup in b: x = tup temp_array = [] for num in x: split_number = re.search(r'\d+', num).group() temp_array.append(split_number) difference = int(max(temp_array)) - int(min(temp_array)) final_array.append(difference) print(final_array)
Count of sub-strings that contain character X at least once. E.g Input: str = “abcd”, X = ‘b’ Output: 6
This question was asked in an exam but my code (given below) passed just 2 cases out of 7 cases. Input Format : single line input seperated by comma Input: str = “abcd,b” Output: 6 “ab”, “abc”, “abcd”, “b”, “bc” and “bcd” are the required sub-strings. def slicing(s, k, n): loop_value = n - k + 1 res = [] for i in range(loop_value): res.append(s[i: i + k]) return res x, y = input().split(',') n = len(x) res1 = [] for i in range(1, n + 1): res1 += slicing(x, i, n) count = 0 for ele in res1: if y in ele: count += 1 print(count)
When the target string (ts) is found in the string S, you can compute the number of substrings containing that instance by multiplying the number of characters before the target by the number of characters after the target (plus one on each side). This will cover all substrings that contain this instance of the target string leaving only the "after" part to analyse further, which you can do recursively. def countsubs(S,ts): if ts not in S: return 0 # shorter or no match before,after = S.split(ts,1) # split on target result = (len(before)+1)*(len(after)+1) # count for this instance return result + countsubs(ts[1:]+after,ts) # recurse with right side print(countsubs("abcd","b")) # 6 This will work for single character and multi-character targets and will run much faster than checking all combinations of substrings one by one.
Here is a simple solution without recursion: def my_function(s): l, target = s.split(',') result = [] for i in range(len(l)): for j in range(i+1, len(l)+1): ss = l[i] + l[i+1:j] if target in ss: result.append(ss) return f'count = {len(result)}, substrings = {result}' print(my_function("abcd,b")) #count = 6, substrings = ['ab', 'abc', 'abcd', 'b', 'bc', 'bcd']
Here you go, this should help from itertools import combinations output = [] initial = input('Enter string and needed letter seperated by commas: ') #Asking for input list1 = initial.split(',') #splitting the input into two parts i.e the actual text and the letter we want common in output text = list1[0] final = [''.join(l) for i in range(len(text)) for l in combinations(text, i+1)] #this is the core part of our code, from this statement we get all the available combinations of the set of letters (all the way from 1 letter combinations to nth letter) for i in final: if 'b' in i: output.append(i) #only outputting the results which have the required letter/phrase in it
How to speed up combination algorithm?
Code below finds minimum items of list B that forms string A. lets assume A='hello world how are you doing' and B=['hello world how', 'hello are' ,'hello', 'hello are you doing']. Then since items with index 0 and 3 contains all words of string A, the answer will be 2. I converted all the strings to integer to speed up the algorithm, but since there are larger and complicated test cases I need more optimized algorithm. I wondering how to speed up this algorithm. import itertools A='hello world how are you doing' B=['hello world how', 'hello are' ,'hello', 'hello are you doing'] d = {} res_A = [d.setdefault(word, len(d)+1) for word in A.lower().split()] mapping = dict(zip(A.split(), range(1, len(A) + 1))) # find mappings of words in B res_B = [[mapping[word] for word in s.split()] for s in B] set_a = set(res_A) solved = False for L in range(0, len(res_B)+1): for subset in itertools.combinations(res_B, L): s = set(item for sublist in subset for item in sublist) if set_a.issubset(s): print(f'{L}') solved = True break if solved: break
I Had a logic mistake on remove_sub, no idea why it still worked try cleaning the data and reducing as much items from b import itertools as it import time import numpy as np from collections import Counter, defaultdict as dd import copy A='hello world how are you doing' B=['hello world how', 'hello are' ,'hello', 'hello are you doing'] d = {} res_A = [d.setdefault(word, len(d)+1) for word in A.lower().split() mapping = dict(zip(A.split(), range(1, len(A) + 1))) # find mappings of words in B res_B = [[mapping[word] for word in s.split()] for s in B] set_a = set(res_A) # my adding works on list of sets for i in range(len(res_B)): res_B[i] = set(res_B[i]) # a is a list of numbers, b is a list of sets of numbers, we are trying to cover a using min items from b a = np.random.randint(0,50,size = 30) np_set_a = set(a) b = [] for i in range(200): size = np.random.randint(0,20) b.append(set(np.random.choice(a,size))) # till here, created a,b for larger data test def f1(set_a, b): solved = False for L in range(0, len(b)+1): for subset in it.combinations(b, L): s = set(item for sublist in subset for item in sublist) if set_a.issubset(s): print(f'{L}','**************f1') solved = True break if solved: break def rare(b): c = Counter() #a dict where the key is a num and the value is how many times this num appears on all b sets items = dd(list) # dict where the key is num and value is list of index where this num exist in b for i in range(len(b)): c.update(b[i]) for num in b[i]: items[num].append(i) rare = set() common = c.most_common() #return sorted list of tuples with a number and how many times it appear for i in range(1,len(common)-1): #take all the numbers that appear only once on b, these items will have to be on the final combination so you can remove them from b and their numbers from a because those numbers are covered if common[-i][1] ==1: rare.add(common[0]) continue break rare_items = {} # a set of all index that have rare number in them for k in rare: rare_items.update(items[k]) values_from_rare_items = set() # a set of all the numbers in the items with the rare numbers for i in rare_items: values_from_rare_items.update(b[i]) for i in reversed(sorted(rare_items)): #remove from b all the items with rare numbers, because they have to be on the final combination, you dont need to check them b.pop(i) return values_from_rare_items,b, len(rare_items) #check sets on b, if 2 are equal remove 1, if 1 is a subset of the other, remove it def remove_sub(b): to_pop = set() t = copy.deepcopy(b) for i in range(len(b)): for j in range(len(t)): if i ==j: continue if b[i] == t[j]: to_pop.add(i) continue if b[i].issubset(t[j]): to_pop.add(i) if t[j].issubset(b[i]): to_pop.add(j) for i in reversed(sorted(to_pop)): b.pop(i) return b def f2(set_a, b): b1 = remove_sub(b) values_from_rare_items,b2, num_rare_items = rare(b) a_without_rare = set_a-values_from_rare_items #remove from a all the number you added with the rare unique numbers, they are already covered solved = False for L in range(0, len(b2)+1): for subset in it.combinations(b2, L): s = set(item for sublist in subset for item in sublist) if a_without_rare.issubset(s): length = L+num_rare_items print(f'{length}', "*********f2") solved = True break if solved: break s = time.time() f1(set_a,b) print(time.time()-s,'********************f1') s = time.time() f2(set_a,b) print(time.time()-s,'******************f2') s = time.time() f1(set_a,res_B) print(time.time()-s,'********************f1') s = time.time() f2(set_a,res_B) print(time.time()-s,'******************f2') this is the out put 2 **************f1 0.16755199432373047 ********************f1 num_array 2 *********f2 0.09078240394592285 ******************f2 num_array 2 **************f1 0.0009989738464355469 ********************f1 your_data 2 *********f2 0.0009975433349609375 ******************f2 your_data you can improve it more by taking all item that appear just few times, and treat them as if they appear once, in rare cases it will not be the real min number, but the time improvement is significant
list object not callable project euler 59
I am trying to do project euler problem 59, i am having an issue in that one of the necessary methods won't work as the program returns: xorNum = test(f,j) TypeError: 'list' object is not callable. Both f and j are integers and when I used the test method with two random integers, it worked perfectly. Does anyone have any ideas why it may not be working? def main(): cipherText = """79,59,12,2,79,35,8,28,20,2,3,68,8,9,68,45,0,12,9,67,68,4,7,5,23,27,1,21,79,85,78,79,85,71,38,10,71,27,12,2,79,6,2,8,13,9,1,13,9,8,68,19,7,1,71,56,11,21,11,68,6,3,22,2,14,0,30,79,1,31,6,23,19,10,0,73,79,44,2,79,19,6,28,68,16,6,16,15,79,35,8,11,72,71,14,10,3,79,12,2,79,19,6,28,68,32,0,0,73,79,86,71,39,1,71,24,5,20,79,13,9,79,16,15,10,68,5,10,3,14,1,10,14,1,3,71,24,13,19,7,68,32,0,0,73,79,87,71,39,1,71,12,22,2,14,16,2,11,68,2,25,1,21,22,16,15,6,10,0,79,16,15,10,22,2,79,13,20,65,68,41,0,16,15,6,10,0,79,1,31,6,23,19,28,68,19,7,5,19,79,12,2,79,0,14,11,10,64,27,68,10,14,15,2,65,68,83,79,40,14,9,1,71,6,16,20,10,8,1,79,19,6,28,68,14,1,68,15,6,9,75,79,5,9,11,68,19,7,13,20,79,8,14,9,1,71,8,13,17,10,23,71,3,13,0,7,16,71,27,11,71,10,18,2,29,29,8,1,1,73,79,81,71,59,12,2,79,8,14,8,12,19,79,23,15,6,10,2,28,68,19,7,22,8,26,3,15,79,16,15,10,68,3,14,22,12,1,1,20,28,72,71,14,10,3,79,16,15,10,68,3,14,22,12,1,1,20,28,68,4,14,10,71,1,1,17,10,22,71,10,28,19,6,10,0,26,13,20,7,68,14,27,74,71,89,68,32,0,0,71,28,1,9,27,68,45,0,12,9,79,16,15,10,68,37,14,20,19,6,23,19,79,83,71,27,11,71,27,1,11,3,68,2,25,1,21,22,11,9,10,68,6,13,11,18,27,68,19,7,1,71,3,13,0,7,16,71,28,11,71,27,12,6,27,68,2,25,1,21,22,11,9,10,68,10,6,3,15,27,68,5,10,8,14,10,18,2,79,6,2,12,5,18,28,1,71,0,2,71,7,13,20,79,16,2,28,16,14,2,11,9,22,74,71,87,68,45,0,12,9,79,12,14,2,23,2,3,2,71,24,5,20,79,10,8,27,68,19,7,1,71,3,13,0,7,16,92,79,12,2,79,19,6,28,68,8,1,8,30,79,5,71,24,13,19,1,1,20,28,68,19,0,68,19,7,1,71,3,13,0,7,16,73,79,93,71,59,12,2,79,11,9,10,68,16,7,11,71,6,23,71,27,12,2,79,16,21,26,1,71,3,13,0,7,16,75,79,19,15,0,68,0,6,18,2,28,68,11,6,3,15,27,68,19,0,68,2,25,1,21,22,11,9,10,72,71,24,5,20,79,3,8,6,10,0,79,16,8,79,7,8,2,1,71,6,10,19,0,68,19,7,1,71,24,11,21,3,0,73,79,85,87,79,38,18,27,68,6,3,16,15,0,17,0,7,68,19,7,1,71,24,11,21,3,0,71,24,5,20,79,9,6,11,1,71,27,12,21,0,17,0,7,68,15,6,9,75,79,16,15,10,68,16,0,22,11,11,68,3,6,0,9,72,16,71,29,1,4,0,3,9,6,30,2,79,12,14,2,68,16,7,1,9,79,12,2,79,7,6,2,1,73,79,85,86,79,33,17,10,10,71,6,10,71,7,13,20,79,11,16,1,68,11,14,10,3,79,5,9,11,68,6,2,11,9,8,68,15,6,23,71,0,19,9,79,20,2,0,20,11,10,72,71,7,1,71,24,5,20,79,10,8,27,68,6,12,7,2,31,16,2,11,74,71,94,86,71,45,17,19,79,16,8,79,5,11,3,68,16,7,11,71,13,1,11,6,1,17,10,0,71,7,13,10,79,5,9,11,68,6,12,7,2,31,16,2,11,68,15,6,9,75,79,12,2,79,3,6,25,1,71,27,12,2,79,22,14,8,12,19,79,16,8,79,6,2,12,11,10,10,68,4,7,13,11,11,22,2,1,68,8,9,68,32,0,0,73,79,85,84,79,48,15,10,29,71,14,22,2,79,22,2,13,11,21,1,69,71,59,12,14,28,68,14,28,68,9,0,16,71,14,68,23,7,29,20,6,7,6,3,68,5,6,22,19,7,68,21,10,23,18,3,16,14,1,3,71,9,22,8,2,68,15,26,9,6,1,68,23,14,23,20,6,11,9,79,11,21,79,20,11,14,10,75,79,16,15,6,23,71,29,1,5,6,22,19,7,68,4,0,9,2,28,68,1,29,11,10,79,35,8,11,74,86,91,68,52,0,68,19,7,1,71,56,11,21,11,68,5,10,7,6,2,1,71,7,17,10,14,10,71,14,10,3,79,8,14,25,1,3,79,12,2,29,1,71,0,10,71,10,5,21,27,12,71,14,9,8,1,3,71,26,23,73,79,44,2,79,19,6,28,68,1,26,8,11,79,11,1,79,17,9,9,5,14,3,13,9,8,68,11,0,18,2,79,5,9,11,68,1,14,13,19,7,2,18,3,10,2,28,23,73,79,37,9,11,68,16,10,68,15,14,18,2,79,23,2,10,10,71,7,13,20,79,3,11,0,22,30,67,68,19,7,1,71,8,8,8,29,29,71,0,2,71,27,12,2,79,11,9,3,29,71,60,11,9,79,11,1,79,16,15,10,68,33,14,16,15,10,22,73""" asciiDict = {} #create ascii table dictionary with number as key asciiDict2 = {} #reverse key value of above dictionary for char in range(256): keyVal = "%d: %c" % (char, char) slicer = keyVal.index(':') key = keyVal[0:slicer] val = keyVal[slicer+2:] asciiDict[int(key)] = val for key in asciiDict.keys(): newVal = asciiDict[key] asciiDict2[newVal] = key newlist = [int(n) for n in cipherText.split(',')] #convert cipher text into list of numbers listOfThreeChars = [] for n in range(len(newlist)): listOfThreeChars.append(newlist[n:n+3]) #create list of groups of three consecutive numbers in cipherText mostCommonDict = mostCommon(listOfThreeChars) mostFrequent3 = mostCommonDict[max(mostCommonDict.keys())] #most common three consecutive numbers, if the key is right these #numbers will become a common three letter word such as 'the' print testCipher(asciiDict,asciiDict2, 'jhd', mostFrequent3) def testCipher(asciiDict,asciiDict2, cipherKey, cipherExtract): cipherKeyAscii = [] test = [] output = [] for k in cipherKey: asciiNum = asciiDict2[k] cipherKeyAscii.append(asciiNum) print cipherKeyAscii for i in range(len(cipherKeyAscii)): f,j = cipherKeyAscii[i],cipherExtract[i] print type(f), type(j),f,j xorNum = test(f,j) #HERE IS WHERE THE PROBLEM IS test.append(xorNum) for final in test: letter = asciiDict[final] output.append(letter) return output def mostCommon(lst): #find most common three consecutive number combinations in text dic = {} for three in lst: key = three count = [] for n in lst: if n == key: count.append(1) dic[len(count)] = key return dic #return max(set(sum(lst, [])), key=sum(lst, []).count) def toBinary(decimalNumber): quotient = 1 remainder = 0 tmpNum = decimalNumber finalNumberList = [] n = "" #e.g. take 14... while quotient != 0: remainder = decimalNumber % 2 #14 % 2 = 0 quotient = decimalNumber / 2 #14 / 2 = 7 decimalNumber = quotient # 7 % 2 = 1 and so on... finalNumberList.insert( 0, remainder ) # Used because all numbers are in a list, i.e. convert to string for num in finalNumberList: n += str( num ) return n def XOR(number1, number2): number1List = [] number2List = [] XORoutput = [] for i in str(number1): #turn both binary numbers into lists number1List.append(int(i)) for i in str(number2): number2List.append(int(i)) if len(number1List)>len(number2List): #make sure they are same lengths diff = len(number1List) - len(number2List) for i in range(diff): number2List.insert(0,0) for i in range(len(number1List)): #XOR it if number1List[i] == number2List[i]: XORoutput.append(0) if number1List[i] != number2List[i]: XORoutput.append(1) num = int(''.join(map(str,XORoutput))) #turn XOR list into int return num def test(num1, num2): #convert input to binary and xor and return to integer print num1,num2 bin1 = toBinary(num1) #turn to binary bin2 = toBinary(num2) xor = XOR(bin1,bin2) #XOR output = int(str(xor),2) #return to number return output if __name__ == "__main__": #print main.__doc__ main()
You set test to a list; you cannot have both a function and a list use the same name: def main(): # other code test = [] # more code for i in range(len(cipherKeyAscii)): # more irrelevant code xorNum = test(f,j) test.append(xorNum) masking the function test(). You even use test as a list again on the very next line. Rename the list, or rename the function. Most of all, pick better, clearer names for your variables.
You defined test to be a list. You also defined it to be a function. De-conflict your names and you should be good to go.