Python String to Array conversion - python

My requirement is to take 'arrList' string as an argument from main and split it using comma (,) and each name is an Array (arr1, arr2, arr3). Now all 3 arrays should be appended to a list. The output should be : list: 1,2,3,7,8,9,11,22,33. But should follow below steps only while implementing.
Tried below code, but not able to convert. Any help is appreciated.
arr1 = [1,2,3]
arr2 = [7,8,9]
arr3 = [11,22,33]
list = []
def arrTest(arrList):
var = arrList.split(',')
for x in var:
#f = open(, "r")
#for x in f:
# list.append(x.rstrip('\n'))
if __name__ == '__main__':
arrList = "arr1,arr2,arr3"
arrTest(arrList)

arr1 = [1,2,3]
arr2 = [7,8,9]
arr3 = [11,22,33]
the_list = []
arrList = "arr1,arr2,arr3"
for array in arrList.split(','):
if array in locals():
the_list.extend(locals()[array])
print (the_list)
Output
[1, 2, 3, 7, 8, 9, 11, 22, 33]
locals() function returns a dictionary containing the variables defined in the local namespace.

You can use python dict data structure.
arr1 = [1,2,3]
arr2 = [7,8,9]
arr3 = [11,22,33]
d = {"arr1": arr1, "arr2": arr2, "arr3": arr3}
def arrTest(arrList):
l = []
var = arrList.split(',')
for x in var:
for e in d[x]:
l.append(e)
return l
if __name__ == '__main__':
arrList = "arr1,arr2,arr3"
l = arrTest(arrList)
print(l)
Output
[1, 2, 3, 7, 8, 9, 11, 22, 33]

Use eval function
arr1 = [1,2,3]
arr2 = [7,8,9]
arr3 = [11,22,33]
out = []
def arrTest(arrList):
list_strs = arrList.split(',')
for list_str in list_strs:
l = eval(list_str)
out.extend(l)
arrList = "arr1,arr2,arr3"
arrTest(arrList)
print(out)
[1, 2, 3, 7, 8, 9, 11, 22, 33]

Related

finding the indices of the most maximum values in a list effectively

Suppose we have a list: [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
I want to write a function that returns the indices of the first 3 maximum values in order.
For example in this case the results would be: [8, 5, 7]
I know one way is to write nested-loops, however, can there be any other effective way to achieve this?
Use heapq.nlargest to find the n largest values.
from heapq import nlargest
from operator import itemgetter
l = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
indices_of_3_largest = [i for i,_ in nlargest(3, enumerate(l), itemgetter(1))]
print(indices_of_3_largest)
# [8, 5, 7]
zip the list with the indices, sort it, and take the first 3 values
lst = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
indices = [i for _, i in sorted(zip(lst, range(len(lst))), reverse=True)[:3]]
print(indices) # [8, 5, 7]
This can generate the result in one step, but the less elegant dunder method is used as the key:
>>> lst = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
>>> heapq.nlargest(3, range(len(lst)), lst.__getitem__)
[8, 5, 7]
lambda function do this things easier.
Code:
def sort_index(lst, rev=True):
index = range(len(lst))
s = sorted(index, reverse=rev, key=lambda i: lst[i])
return s
score = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
sort_index(score)[:3]
Result:
[8, 5, 7]
l = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
list(map(lambda x: l.index(x), sorted(l, reverse=True)[:3] )) # [8, 5, 7]
Using consecutive max to a copy of the list.
lst = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
lst_cp = lst.copy()
indeces_max = []
for _ in range(3):
m = max(lst_cp)
indeces_max.append(lst.index(m))
lst_cp.remove(m)
del lst_cp # just to remember that is not needed
print(indeces_max)
You could use np.argsort:
import numpy as np
ar = [1, 3.5, -1, 7, 10, 20, 5, 17, 31, -5]
ar_argsort = np.argsort(ar)
reversed_argsort = ar_argsort[::-1]
indices_3_max = reversed_argsort[0:3]
print(indices_3_max)
Result:
[8 5 7]
Concise version of above in one line:
ar_argsort = np.argsort(ar)[::-1][0:3]
While all 6 answers (right now available after ~24h) are effective in providing the requested result I was wondering which solution is the most efficient one.
I used timeit for the comparison (only runtime, no memory usage, 5k runs with an increased input list - the same for all).
Results in increasing order:
consecutive_max: 2.604 s
heapq_oneStep: 3.052 s
np_argsort: 3.234 s
lambda_unnamed: 6.182 s
heapq_nlargest: 4.522 s
lambda_function: 9.960 s
zip_sort: 15.402 s
Code of the evaluation:
import timeit
timeit_runs = 5_000
# heapq_oneStep by Mechanic Pic
# https://stackoverflow.com/a/73568080/11815313
def heapq_oneStep():
timeit_setup_heapq_oneStep = '''
import heapq
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_heapq_oneStep = '''
heapq.nlargest(3, range(len(lst)), lst.__getitem__)
'''
return timeit.timeit(stmt=testcode_heapq_oneStep,
setup=timeit_setup_heapq_oneStep, number = timeit_runs)
# heapq_nlargest by Stef
# https://stackoverflow.com/a/73567876/11815313
def heapq_nlargest():
timeit_setup_heapq_nlargest = '''
from heapq import nlargest
from operator import itemgetter
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_heapq_nlargest = '''
[i for i,_ in nlargest(3, enumerate(lst), itemgetter(1))]
'''
return timeit.timeit(stmt=testcode_heapq_nlargest,
setup=timeit_setup_heapq_nlargest, number = timeit_runs)
# zip_sort by Guy
# https://stackoverflow.com/a/73567874/11815313
def zip_sort():
timeit_setup_zip_sort = '''
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_zip_sort = '''
[i for _, i in sorted(zip(lst, range(len(lst))), reverse=True)[:3]]
'''
return timeit.timeit(stmt=testcode_zip_sort,
setup=timeit_setup_zip_sort, number = timeit_runs)
# lambda_function by Mehmaam
# https://stackoverflow.com/a/73568027/11815313
def lambda_function():
timeit_setup_lambda_function = '''
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_lambda_function = '''
def sort_index(lst, rev=True):
index = range(len(lst))
s = sorted(index, reverse=rev, key=lambda i: lst[i])
return s
sort_index(lst)[:3]
'''
return timeit.timeit(stmt=testcode_lambda_function,
setup=timeit_setup_lambda_function, number = timeit_runs)
# lambda_unnamed by uozcan12
# https://stackoverflow.com/a/73569339/11815313
def lambda_unnamed():
timeit_setup_lambda_unnamed = '''
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_lambda_unnamed = '''
list(map(lambda x: lst.index(x), sorted(lst, reverse=True)[:3] ))
'''
return timeit.timeit(stmt=testcode_lambda_unnamed,
setup=timeit_setup_lambda_unnamed, number = timeit_runs)
# np_argsort by MagnusO_O
# https://stackoverflow.com/a/73567884/11815313
def np_argsort():
timeit_setup_np_argsort = '''
import numpy as np
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
lst_nparr = np.array(lst)
'''
testcode_np_argsort = '''
lst_nparr_max3 = np.argsort(lst_nparr)[::-1][0:3]
lst_nparr_max3.tolist()
'''
return timeit.timeit(stmt=testcode_np_argsort,
setup=timeit_setup_np_argsort, number = timeit_runs)
# consecutive_max by cards
def consecutive_max():
timeit_setup_consecutive_max = '''
import random
random.seed(42)
integer_list = random.sample(range(-10_000, 10_000), 10_000)
lst = [x/100 for x in integer_list]
'''
testcode_consecutive_max = '''
lst_cp = lst.copy()
indeces_max = []
for _ in range(3):
m = max(lst_cp)
indeces_max.append(lst.index(m))
lst_cp.remove(m)
'''
return timeit.timeit(stmt=testcode_consecutive_max,
setup=timeit_setup_consecutive_max, number = timeit_runs)
time_heapq_oneStep = heapq_oneStep()
time_heapq_nlargest = heapq_nlargest()
time_zip_sort = zip_sort()
time_lambda_function = lambda_function()
time_lambda_unnamed = lambda_unnamed()
time_np_argsort = np_argsort()
time_consecutive_max = consecutive_max()
print(f'''consecutive_max: {time_consecutive_max:.3f} s''')
print(f'''np_argsort: {time_np_argsort:.3f} s''')
print(f'''heapq_oneStep: {time_heapq_oneStep:.3f} s''')
print(f'''lambda_unnamed: {time_lambda_unnamed:.3f} s''')
print(f'''heapq_nlargest: {time_heapq_nlargest:.3f} s''')
print(f'''lambda_function: {time_lambda_function:.3f} s''')
print(f'''zip_sort: {time_zip_sort:.3f} s''')

Can anyone help me in handling ties in a python list while I try to replace it's elements with their ranks?

I have a list that looks something like this:
lst_A = [32,12,32,55,12,90,32,75]
I want to replace the numbers with their rank. I am using this function to do this:
def obtain_rank(lstC):
sort_data = [(x,i) for i,x in enumerate(lstC)]
sort_data = sorted(sort_data,reverse=True)
result = [0]*len(lstC)
for i,(_,idx) in enumerate(sort_data,1):
result[idx] = i
return result
I am getting the following output while I use this:
[6, 8, 5, 3, 7, 1, 4, 2]
But what I want from this is:
[4, 7, 5, 3, 8, 1, 6, 2]
How can I go about this?
Try this:
import pandas as pd
def obtain_rank(a):
s = pd.Series(a)
return [int(x) for x in s.rank(method='first', ascending=False)]
#[4, 7, 5, 3, 8, 1, 6, 2]
You could use 2 loops:
l = [32,12,32,55,12,90,32,75]
d = list(enumerate(sorted(l, reverse = True), start = 1))
res = []
for i in range(len(l)):
for j in range(len(d)):
if d[j][1] == l[i]:
res.append(d[j][0])
del d[j]
break
print(res)
#[4, 7, 5, 3, 8, 1, 6, 2]
Here you go. In case, you are not already aware, please read https://docs.python.org/3.7/library/collections.html to understand defaultdict and deque
from collections import defaultdict, deque
def obtain_rank(listC):
sorted_list = sorted(listC, reverse=True)
d = defaultdict(deque) # deque are efficient at appending/popping elements at both sides of the sequence.
for i, ele in enumerate(sorted_list):
d[ele].append(i+1)
result = []
for ele in listC:
result.append(d[ele].popleft()) # repeating numbers with lower rank will be the start of the list, therefore popleft
return result
Update: Without using defaultdict and deque
def obtain_rank(listC):
sorted_list = sorted(listC, reverse=True)
d = {}
for i, ele in enumerate(sorted_list):
d[ele] = d.get(ele, []) + [i + 1] # As suggested by Joshua Nixon
result = []
for ele in listC:
result.append(d[ele][0])
del d[ele][0]
return result

dropping the lowest values from a list

I'm trying to write a python program that drops 25% of the lowest values from a list and (return the original unsorted list). For example;
Input : [1,5,6,72,3,4,9,11,3,8]
Output : [5,6,72,4,9,11,8]
I tried to do:
l = [1,5,6,72,3,4,9,11,3,8]
def drop(k):
while len(l)!=0 and k > 0:
k = k - 1
l.sort(reverse = True)
l.pop()
return l
k = math.ceil(len(l) * 0.25)
drop (k)
it returns [72, 11, 9, 8, 6, 5, 4] but is there a way to do it without sorting?.
You don't require to reverse sort and find the smallest element. Use min on list l which returns the smallest value from l and remove using l.remove conveniently.
import math
l = [1,5,6,72,3,4,9,11,3,8]
def drop(k):
while len(l)!=0 and k > 0:
k = k - 1
l.remove(min(l))
return l
k = math.ceil(len(l) * 0.25)
print(drop (k))
# [5, 6, 72, 4, 9, 11, 8]
You could use a heapq and keep popping elements until 25% of the container has been removed. Then, filter the contents of the original list
import heapq, copy
s = [1,5,6,72,3,4,9,11,3,8]
new_s = copy.deepcopy(s)
heapq.heapify(s)
count = 0
last_items = set()
while count/float(len(new_s)) <= 0.25:
last_items.add(heapq.heappop(s))
count += 1
final_s = [i for i in new_s if i not in last_items]
Output:
[5, 6, 72, 4, 9, 11, 8]
There are O(n) solutions to this problem. One of those, introselect, is implemented in numpy in the partition and argpartition functions:
>>> data = [1,5,6,72,3,4,9,11,3,8]
>>>
>>> k = int(round(len(data) / 4))
>>>
>>> import numpy as np
>>> dnp = np.array(data)
>>> drop_them = np.argpartition(dnp, k)[:k]
>>> keep_them = np.ones(dnp.shape, dtype=bool)
>>> keep_them[drop_them] = False
>>> result = dnp[keep_them].tolist()
>>>
>>> result
[5, 6, 72, 4, 9, 11, 3, 8]
Note that this method keeps one of the 3s and drops the other one in order to get the split at exactly k elements.
If instead you want to treat all 3s the same, you could do
>>> boundary = np.argpartition(dnp, k)[k]
>>> result = dnp[dnp > dnp[boundary]]
>>>
>>> result
array([ 5, 6, 72, 4, 9, 11, 8])
One way of doing this is this is very slow especially for longer lists!:
quart_len = int(0.25*len(l))
for i in range(quart_len):
l.remove(min(l))
A much faster way of doing this:
import numpy as np
from math import ceil
l = [1,5,6,72,3,4,9,11,3,8]
sorted_values = np.array(l).argsort()
l_new = [l[i] for i in range(len(l)) if i in sorted_values[int(ceil(len(l)/4.)):]]
Another approach:
l = np.array(l)
l = list(l[l > sorted(l)[len(l)/4]])
l1=[1,5,6,72,3,4,9,11,3,8]
l2=sorted(l1)
ln=round(len(l1)*0.25)
[i for i in l1 if i not in l2[ln+1:]]
Output:
[5, 6, 72, 4, 9, 11, 8]

matrix multiplying between files in python

import linecache
fileA = open('matrixA.txt', 'r' )
line2 = linecache.getline('matrixA.txt', 2)
line3 = linecache.getline('matrixA.txt', 3)
line4 = linecache.getline('matrixA.txt', 4)
two = line2.split()
list2 = list(map(int, two))
three = line3.split()
list3 = list(map(int,three))
four = line4.split()
list4 = list(map(int, four))
listA = [list2]+[list3]+[list4]
print (listA)
fileB = open('matrixB.txt', 'r')
Bline2 = linecache.getline('matrixB.txt', 2)
Bline3 = linecache.getline('matrixB.txt', 3)
Bline4 = linecache.getline('matrixB.txt', 4)
btwo = Bline2.split()
blist2 = list(map(int, btwo))
bthree = Bline3.split()
blist3 = list(map(int,bthree))
bfour = Bline4.split()
blist4 = list(map(int, bfour))
listB = [blist2] + [blist3] + [blist4]
print (listB)
q = listA[0] #
h = listB[0] #This part dosn't work
aq = q*h #
print(aq) #
//for i in range(listA):
So I have this code so far from my 2 files file A prints as:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
And file B prints as:
[[3, 3, 9], [7, 4, 8], [4, 20, 30]]
How would I get these two matrices to multiply, I know you would need positions but I don't know how to do the loop.
I assume you have loaded your *.txt data correctly (you start to read your data from the second line), then to multiply it the simple one is by converting it to numpy array and use np.dot.
import numpy as np
A = np.asarray(listA)
B = np.asarray(listB)
res = np.dot(B,A)
print(res)
or you can do that without numpy by indexing the list:
res = [[0] * len(listA[0]) for _ in range(len(listB))]
for i in range(len(listB)):
for j in range(len(listA[0])):
for k in range(len(listA)):
res[i][j] += listB[i][k]*listA[k][j]
print(res)
to make sure your matrix can be multiplied, check the dimension first:
if len(listA)==len(listB[0]):
res = [[0] * len(listA[0]) for _ in range(len(listB))]
for i in range(len(listB)):
for j in range(len(listA[0])):
for k in range(len(listA)):
res[i][j] += listB[i][k]*listA[k][j]
print(res)
else:
print("ERROR! Size Mismatch")

Appending elements to a list based on condition

I was trying to append few elements to a list list_accepted_outsidenestant. When i try to print the list list_accepted_outsidenestant, i get: list_accepted_outsidenestant- [([971, 977, 728, 740], set([728, 977, 971, 740]))]. The list is showing a list and set with same elements. Can anyone pointout the mistake i am doing? Because of this, i am getting an error:
set_accepted_outsidenest_antlist = set(list_accepted_outsidenestant
TypeError: unhashable type: 'list'
I have shown part of code only relevant to the current question.
def leo(tag_data):
available_ants_outside = []
ori = []
for id, (x, y) in tag_data:
available_ants_outside.append(id)
if for_coordinates_outside_nest((x, y)) is True:
ori.append(id)
return ori
def virgo(tag_data):
available_ants_inside = []
list_insidenest_ant_id = []
set_inside_nest_ant_id = set()
for id, (x, y) in tag_data:
available_ants_inside.append(id)
if for_coordinates_inside_nest((x, y)) is True:
list_insidenest_ant_id.append(id)
set_inside_nest_ant_id = set(list_insidenest_ant_id)
return list_insidenest_ant_id,set_inside_nest_ant_id
def bambino(ori,list_insidenest_ant_id):
list_accepted_outsidenestant = []
set_accepted_outsidenest_antlist = set()
set_accepted_insidenest_antlist = set()
if len(list_accepted_outsidenestant) < num_accepted:
if (len(ori) > 0) or (len(list_insidenest_ant_id) >0):
list_accepted_outsidenestant.extend(ori[0:min(len(ori),
num_accepted-len(list_accepted_outsidenestant))])
set_accepted_outsidenest_antlist = set(list_accepted_outsidenestant)
print "list_accepted_outsidenestant-" + str(list_accepted_outsidenestant)
set_accepted_insidenest_antlist = set(list_insidenest_ant_id)
return set_accepted_outsidenest_antlist,set_list_outsideant_id,set_accepted_insidenest_antlist
The problem is that you're appending a list to a list.
You can either iterate over the list you want to add:
items_to_add = ori[0:min(len(ori),
num_accepted-len(list_accepted_outsidenestant))]
for item in items_to_add:
list_accepted_outsidenestant.append(item)
Or add the lists:
list_accepted_outsidenestant = list_accepted_outsidenestant + ori[0:min(len(ori), num_accepted-len(list_accepted_outsidenestant))]
Or as bruno pointed out (even better), extend the list.
list_accepted_outsidenestant.extend(ori[0:min(len(ori), num_accepted-len(list_accepted_outsidenestant))])
append function add whole into other array
extend function extend add array into previous array
In [1]: a = [1,2,3,4]
In [2]: b = [10,9,8,7,6]
In [3]: a.append(b)
In [4]: a
Out[4]: [1, 2, 3, 4, [10, 9, 8, 7, 6]]
In [5]: c = [1,2,3,4]
In [6]: c.extend(b)
In [7]: c
Out[7]: [1, 2, 3, 4, 10, 9, 8, 7, 6]
Hope this code help you

Categories