Replacing items in a two dimensional list in python - python

I am trying to append the second item in my two dimensional.
I have tried a few dozen different ways and can't seem to get it to append.
def main():
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
user = int(input('Enter a whole number'))
for i in range(len(values)):
print(values[i])
(current out put)
10, 0
13, 0
36, 0
74, 0
22, 0
(were the second part it is values[0] + user input)
[10, 12]
[13, 15]
[36, 38]
[74, 76]
[22, 24]

with list comprehension
user = 2
[[x[0], sum(x)+user] for x in values]
>>> [[10, 12], [13, 15], [36, 38], [74, 76], [22, 24]]
or using map:
map(lambda x: [x[0], sum(x)+user], values)

First, you can nearly always avoid iterating over range(len(iterable)) - in this case, your loop can be written as the much nicer:
for value in values:
print(value)
for exactly the same functionality.
I'm not sure from your description exactly how you want the code to behave, but it seems like you want something like this - each line of output will have the first item of the corresponding value, and then that added to the user input; ie, ignoring the second item of the existing input entirely:
for value in values:
total = value[0] + user
print((value[0], total))
or if you want it to overwrite the second item of each value for later use in your program:
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
for value in values:
value[1] = value[0] + user
print(value)

Shouldn't it be just like this?
>>> def f():
values = [[10,0], [13, 0], [36, 0], [74,0], [22,0]]
user = int(input('Enter a whole number'))
for i in range(len(values)):
values[i][1]=values[i][0]+user
print(values[i])
>>> f()
Enter a whole number2
[10, 12]
[13, 15]
[36, 38]
[74, 76]
[22, 24]

Related

find index of certain array that is inside array

Is there a way to find an index of an array inside another array without converting them to list or using a for loop?
I have a huge data set and I don't want to add another loop and make it slower
arr = np.array([[11, 19, 18], [14, 15, 11], [19, 21, 46], [29, 21, 19]])
find_this_array = np.array([14, 15, 11])
# I want to avoid this
a = arr.tolist()
val = find_this_array.tolist()
a.index(val)
output:
1
You can try this:
np.where((arr == find_this_array).all(axis=1))[0][0]
output:
1
You can find more details about Numpy where from their documentation:
https://numpy.org/doc/stable/reference/generated/numpy.where.html

How to pick n smallest numbers from a list with nested lists as elements

Consider the following code:
def temporary4(ratio,x,y):
results = []
for x in range(1,x):
results.append(abs((1200*math.log((2**(x/y)),2)-(1200*math.log(ratio,2)))))
return results
def intApprox(ratio,x):
return min(temporary4(ratio,x,x))
Now I use that to make a function that makes a list with a list of 2 elements as elements.
def temporaryTempFinder(ratio):
list1 = []
for x in range(12,61,1):
list1.append([intApprox(ratio,x),x])
return list1
Test:
temporaryTempFinder(3/2)
This returns a list with terms that look like:
[[1.955000865387433, 12],
[36.50653759615102, 13],
[16.240715151101654, 14],
[18.044999134612567, 15],
[26.95500086538732, 16],
[3.927352075789031, 17],
[31.37833246794594, 18],
[7.218158760124197, 19],
[18.044999134612567, 20],
[16.240715151101654, 21],
[7.135908225521689, 22],
[23.69413130017017, 23],
[1.955000865387433, 24],
[18.044999134612567, 25],
[9.647308557695169, 26],
[9.156110245723653, 27],
[16.240715151101654, 28],
[1.4932749966815209, 29],
[18.044999134612567, 30],
[5.180807317000472, 31],
[10.54499913461268, 32],
[11.045909956296327, 33],
[3.927352075789031, 34],
[16.240715151101654, 35],
[1.955000865387433, 36],
[11.558512648126111, 37],
[7.218158760124197, 38],
[5.737306826920303, 39],
[11.95500086538732, 40],
[0.484023524856525, 41],
[12.330713420327015, 42],
[4.280582260736196, 43],
[7.135908225521689, 44],
[8.621667532054175, 45],
[2.3928252215692964, 46],
[12.593298737727878, 47],
[1.955000865387433, 48],
[8.249080767265582, 49],
[5.95500086538766, 50],
[3.927352075789031, 51],
[9.647308557695169, 52],
[0.06820841255716914, 53],
[9.156110245723653, 54],
[3.7731826835693028, 55],
[5.187856277469905, 56],
[7.218158760124197, 57],
[1.4932749966815209, 58],
[9.90940591427352, 59],
[1.955000865387433, 60]]
I successfully made a function that picks the element with the smallest first element from the list and returns the second element of the element:
def topTempFinder(ratio):
list1 = []
for x in range(12,61,1):
list1.append([intApprox(ratio,x),x])
return min(list1)[1]
topTempFinder(3/2)
The Result:
53
This is desired because the element which has 53 as its second element has the smallest first element (0.06820841255716914) (refer to the list above for clarification).
My issue now is that I am trying to pick the top 10 elements with the smallest first element and I want the function to return a list of the SECOND element of the chosen elements.
My attempt:
def temporaryTempFinder2(ratio):
list1 = []
for x in range(12,61,1):
list1.append(intApprox(ratio,x))
return list1
def top10TempFinder(list1):
final_list = []
for i in range(0, 10):
min1 = 100
for j in range(len(list1)):
if list1[j] < min1:
min1 = list1[j];
list1.remove(min1);
final_list.append(min1)
return final_list
list1 = temporaryTempFinder(3/2)
list2 = temporaryTempFinder2(3/2)
Trying the code:
top10TempFinder(list2)
top10TempFinder(list1)
Here is where the issue comes, when I use list2, it works as the list has elements without nested lists, however, with list1 I get the error:
TypeError: '<' not supported between instances of 'list' and 'int'
I would like to know how to deal with this.
I apologize if the language was confusing and hard to follow, I have attempted to provide examples to make things clear.
You can use the sorted() built-in function from python with a key argument or heapq.nsmallest() function from python's standard library.
.sorted() solution
>>> temp = temporaryTempFinder(3/2)
>>> def top10(arr):
... return [i[1] for i in sorted(arr, key=lambda x: x[0])[:10]]
...
>>> top10(temp)
[53, 41, 29, 58, 12, 24, 36, 48, 60, 46]
heapq.nsmallest() solution
>>> import heapq
>>> def top10(arr):
... return [i[1] for i in heapq.nsmallest(10, arr)]
...
>>> top10(temp)
[53, 41, 29, 58, 12, 24, 36, 48, 60, 46]
I think the best approach to this would be to turn your list into a dict then sort that.
info = {l[1]:l[0] for l in lst}
info = dict(sorted(info.items(), key=lambda item: item[1]))
print(list(info.keys())[:10])
output
[53, 41, 29, 58, 12, 24, 36, 48, 60, 46]
#Note: lst is your list.

Operate on a list and replace values

I have the list called 'list_one', which I seek to relate to 'list_relation', to finally have a final list of values, my logic is as follows:
By looping in the range of 'list_one' and for each 'items_relation' of 'list_relation':
1.If 'list_one [i] [0]' is inside 'items_relation', I add the corresponding operation of 'list_one'.
list_one = [[1, 0],
[2, 0],
[3, 0],
[4, 0],
[11, 0],
[12, 0],
[13, 2000],
[14, 3000],
[15, 3500],
[16, 5000],
[17, 6500],
[18, 8800],
[19, 6700],
[20, 280]]
# Code to get this 'list_relation' ...
list_relation = [[13, 14], [15, 16],
[17, 18], [19, 20]]
final = []
for i in range(len(list_one)):
for items_elements in list_relation:
for k in items_elements:
if list_one[i][0] in items_elements:
final.append((list_one[i][1] + list_one[i][0]))
print(final)
I am looking for a list like this:
[[2013, 3014], [3515, 5016], [6517, 8818], [6719, 300]]
What is the best way to do it? Thank you.
list_one appears to be a lookup table - it would make more sense to use a dictionary instead of a list. Then loop through the values of list_relation, do a lookup against the dictionary and add the value if it is there. If it isn't there, get a default value of 0 so it doesn't affect the sum. This also means there is no need to include lookup entries with values of 0:
list_one = {13: 2000, # note choose a better var name
14: 3000,
15: 3500,
16: 5000,
17: 6500,
18: 8800,
19: 6700,
20: 280,}
list_relation = [[13, 14],
[15, 16],
[17, 18],
[19, 20]]
final = [[item + list_one.get(item, 0)
for item in pair]
for pair in list_relation]
You can build a dictionary from list_one and then iterate to create the resulting list.
>>> d = dict(list_one)
>>> final = [[el+d[el] for el in l] for l in list_relation]
>>> final
[[2013, 3014], [3515, 5016], [6517, 8818], [6719, 300]]

How do you find most duplicates in a 2d list?

I have a 2d list that i would like to return the most duplicates by using a list comprehension. For example, i have a list below
a = [[10, 15, 17,],[20,21,27],[10,15,17],[21,27,28],[21,27,28],[5,10,15],[15,17,20]]
I would like my result to be
b = [[10,15,17],[21,27,28]
The common solution for counting repetitions is collections.Counter:
from collections import Counter
a = [[10, 15, 17], [20, 21, 27], [10, 15, 17], [21, 27, 28], [21, 27, 28], [5, 10, 15], [15, 17, 20]]
# count duplicates
counts = Counter(map(tuple, a))
# find the maximum count (the values of counts are the duplicate count)
maximum_count = max(counts.values())
# filter and convert back to list
result = [list(e) for e, count in counts.items() if count == maximum_count]
print(result)
Output
[[10, 15, 17], [21, 27, 28]]
In your case in particular as the elements of the list are list, you need to convert them to tuples (to make them hashable), then just filter the list and keep the elements with maximum count.
One line splitted here:
[ a[k]
for k in range(len(a))
if a.count( a[k] ) > 1
and k == a.index( a[k] ) ]
The simplest way to do this to find the count for each element, and store the maximum count. Then, display all elements that have the maximum count (removing duplicates).
The below code will work for you:
a = [[10, 15, 17,],[20,21,27],[10,15,17],[21,27,28],[21,27,28],[5,10,15],[15,17,20]]
check=0
for i in a:
if a.count(i) > check:
check=a.count(i) #Check to see maximum count
b=[]
for i in a:
if a.count(i) == check: #Choosing elements with maximum count
if i not in b: #Eliminating duplicates
b.append(i)
print(b)
Output:
[[10, 15, 17], [21, 27, 28]]

Search a number in a sorted 2D array

I'm trying to find the number that I'm looking from in a 2D array list. However, it has to be sorted first before searching.
Everything seems to be working fine when I'm trying to find a number in the 2D array. It is just the fact of sorting the 2D array in a way that will still be working. Let's assume I want to sort a 3x3 2D array. The way that it should display is:
[[8, 27, 6],
[1, 0, 11],
[10, 9, 3]]
Then, I will be looking for a number by using the binary search method through the sorted 2D array. My mid value will be in the middle of the array from the search.
This is just an example, but what I want to accomplish when I put randomized numbers and then sort row and columns. Using this idea, I'm using the random.randint() library from Python to randomized my numbers. Then, I'm trying to sort afterward in my 2d array, but it isn't really sorting before continuing.
n = 5
m = 5
def findnum_arr(array, num):
low = 0
high = n * m - 1
while (high >= low):
mid = (low + high) // 2
i = mid // m
j = mid % m
if (num == array[i][j]):
return True
if (num < array[i][j]):
high = mid - 1
else:
low = mid + 1
return False
if __name__ == '__main__':
multi_array = [[random.randint(0, 20) for x in range(n)] for y in range(m)]
sorted(multi_array)
Sorted:
[[0, 1, 3],
[6, 8, 9],
[10, 11, 27]]
Should be the sorted 2D array. Is it possible that both the row and column are sorted respectively with the sorted function?
Calling sorted on a nested list that is just going to sort based on the first index in the list.
Example:
arr = [[8, 27, 6],[1, 0, 11],[10, 15, 3], [16, 12, 14], [4, 9, 13]]
is going to return
[[1, 0, 11], [4, 9, 13], [8, 27, 6], [10, 15, 3], [16, 12, 14]]
To do this way that you want, you are going to have to flatten and then reshape.
To do this, I would try introducing numpy.
import numpy as np
a = np.array(sorted(sum(arr, [])))
#sorted(sum(arr, [])) flattens the list
b = np.reshape(a, (-1,3)).tolist()
EDITED FOR CLARITY: You can use your m and n as parameters in np.reshape. The first parameter (m) would return the number of arrays, while (n) would return the number of arrays.
The use of -1 in either parameter means that the reshaped array will be fit to return the requirements of the other parameter.
b would return
[[0, 1, 3], [4, 6, 8], [9, 10, 11], [12, 13, 14], [15, 16, 27]]
Finally found out a proper solution without using numpy and avoiding sum() module.
if __name__ == '__main__':
x = 7
multi_array = [[random.randint(0, 200) for x in range(n)] for y in range(m)]
# one_array = sorted(list(itertools.chain.from_iterable(multi_array))) Another way if you are using itertools
one_array = sorted([x for row in multi_array for x in row])
sorted_2d = [one_array[i:i+m] for i in range(0, len(one_array), n)]
print("multi_array list is: \n{0}\n".format(multi_array))
print("sorted 2D array: \n{0}\n".format(sorted_2d))
if not findnum_arr(sorted_2d, x):
print("Not Found")
else:
print("Found")
output:
multi_array list is:
[[40, 107, 23, 27, 42], [150, 84, 108, 191, 172], [154, 22, 161, 26, 31], [18, 150, 197, 77, 191], [96, 124, 81, 1
25, 186]]
sorted 2D array:
[[18, 22, 23, 26, 27], [31, 40, 42, 77, 81], [84, 96, 107, 108, 124], [125, 150, 150, 154, 161], [172, 186, 191, 1
91, 197]]
Not Found
I wanted to find a standard library module where I could flat the 2D array into 1D and sort it. Then, I would make a list comprehension of my 1D array and build it into a 2D array to. This sounds a lot of works but seems to work fine. Let me know if there is a better way to do it without numpy and faster :)

Categories

Resources