Find index of item in group of 4 lists - python

Following is a function in python to find index of a input in group of 4.
def mapping(inp_rate=[],inp_rssi=[]):
a1=[6.5,13.0,19.5,26.0,39.0,52.0,58.5,65.0]`
a11=[7.2,14.4,21.7,28.9,43.3,57.8,65.0,72.2]
a2=[13.0,26.0,39.0,52.0,78.0,104.0,117.0,130.0]
a22=[14.4,28.9,43.3,57.8,86.7,115.6,130,144.4]
result_list = []
print inp_rate
for value in inp_rate:
if value in a1:
result_list.append(a1.index(value))
elif value in a11:
result_list.append(a11.index(value))
elif value in a2:
result_list.append(a2.index(value))
elif value in a22:
result_list.append(a22.index(value))
else:
result_list.append(0)
print(result_list)
output is as below:
['65.0', '144.4', '72.2', '72.2']
[0, 0, 0, 0]
As the list items are present in a1,a11,a2,a22, cant understand why the index are 0!

You said you wanted the index, but 65 has an index of 7 in the a1 list. If you want the actual place (where the first item of a list is 1 and not 0) then just add one to the value getting appended to the list.
Also, I've added a print statement when a value isn't in any list, as #Chris mentioned.
a1 = [6.5, 13, 19.5, 26, 39, 52, 58.5, 65]
a11 = [7.2, 14.4, 21.7, 28.9, 43.3, 57.8, 65, 72.2]
a2 = [13, 26, 39, 52, 78, 104, 117, 130]
a22 = [14.4, 28.9, 43.3, 57.8, 86.7, 115.6, 130, 144.4]
inp_rate = [65, 72.2, 72.2, 39, 72.2, 144.4, 78, 13, 72.2, 104, 6.5]
result_list = []
for value in inp_rate:
if value in a1:
result_list.append(a1.index(value))
elif value in a11:
result_list.append(a11.index(value))
elif value in a2:
result_list.append(a2.index(value))
elif value in a22:
result_list.append(a22.index(value))
else:
print("{} cannot be found".format(value))
print(result_list)
This prints
[7, 7, 7, 4, 7, 7, 4, 1, 7, 5, 0]

x = a1 + a11 + a2 + a22
result = [x.index(i)%8+1 if i in x else -1 for i in inp_rate]
result

Hope this helps.
list1 = [ a1,a11,a2,a22]
for i in inp_rate:
c = 0
for j in list1:
if i in j:
c+=1
print(j.index(i),i,j,c)
if c == 1 :
result_list.append(j.index(i)+1)
output:
result_list = [8, 8, 8, 5, 8, 8, 5, 2, 8, 6, 1]

need to put the lists as follows and it worked.
a1=['6.5','13.0','19.5','26.0','39.0','52.0','58.5','65.0']
a11=['7.2','14.4','21.7','28.9','43.3','57.8','65.0','72.2']
a2=['13.0','26.0','39.0','52.0','78.0','104.0','117.0','130.0']
a22=['14.4','28.9','43.3','57.8','86.7','115.6','130.0','144.4']

I don't know wheter it is the most efficent way, but my approach would be:
At first, I'd put the arrays in a tuple for beeing able iterating through them:
arr = (a1, a11, a2, a22)
The next step would be iterating through your inputs and the arrays, checking wheter the number is in the array and then appending the index to a list for the outputs:
out = []
for i in inp_rate:
for j in arr:
if i in j:
output.append(j.index(i))
And as you start counting by 1 and not by 0, you need to add 1 in the append method.

Related

how to grab next-in-line integers from list python

So i have these 2 lists:
list1 = [81, 68, 53, 28, 19, 7, 2, 0]
list1 is fine and nothing would need to happen as there's no numbers (1 up, or 1 below) from any of the nums in list.
list2 = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
Whereas in list2 i have (68,67) (21,20,19) & (1,0)
How can i have a new list be filled with the "extra"(starting from high) next-in-line numbers?
It may or may not be important but just to point out that the list2 will always be sorted from high to low before reaching the below code.
Here's what ive got so far:
####################################################
list2 = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
numbs_list= []
complete = False
i = 0
# start = 0
# end = len(list2) -1
while complete is False:
if len(list2) > 1:
# if index 1 is next-in-line to index 0
# if 67 == 67(68 -1)
if list2[i +1] == list2[i] -1:
# add 68 to numbs list
numbs_list.append(list2[i])
# remove 68 from list2
list2.pop(list2.index(list2[i]))
else:
list2.pop(list2.index(list2[i]))
else:
complete = True
# start += 1
# if start == end:
# complete = True
# from list2 this is what i need numbs_list to have stored once the while loop is done:
numbs_list = [68, 21, 20, 1]
# whats left in list2 does not matter after the numbs_list is finalised as list2 will eventually get cleared and repopulated.
####################################################
"next-in-line" may be the wrong wording but i think you get the idea of what i mean. if not here's some examples:
1,0
11,10,9
23,22
58,57
91,90,89,88
notice how theres no room between any & all of those nums? because theyre all next-in-line.
Try iterating through each index and comparing it to the index - 1. and append the index to the extra list if they are only 1 apart
list2 = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
extra = []
for i in range(1,len(list2)):
if list2[i-1] == list2[i] + 1:
extra.append(list2[i-1])
print(extra)
Using list comprehension:
list2 = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
extra = [list2[i-1] for i in range(1,len(list2)) if list2[i-1] == list2[i]+ 1]
print(extra)
Output
[68, 21, 20, 1]
You have made this far more complicated than it needs to be. Just remember what the last number was, and if the new number is one below it, then add it to your lists.
list2 = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
maybe = []
last = -99
curr = []
for n in list2:
if n == last-1:
maybe[-1].append(n)
else:
maybe.append( [n] )
last = n
numbs_list = [k for k in maybe if len(k) > 1]
print(numbs_list)
This was fun with functools.reduce. Pun definitely intended.
from functools import reduce
lst = [68, 67, 53, 21, 20, 19, 9, 7, 1, 0]
lst2 = reduce(
lambda acc, x:
[[x]] if len(acc) == 0 else
acc[:-1]+[acc[-1]+[x]] if len(acc[-1]) != 0 and acc[-1][-1] == x+1 else
acc+[[x]],
lst,
[]
)
# [[68, 67], [53], [21, 20, 19], [9], [7], [1, 0]]
Once we have this, everything else you might want to figure out is trivial.
lst3 = [y for x in lst2 for y in x if len(x) == 1]
# [53, 9, 7]
lst4 = [x[:-1] for x in lst2 if len(x) > 1]
# [[68], [21, 20], [1]]
lst5 = [y for x in lst2 for y in x[:-1] if len(x) > 1]
# [68, 21, 20, 1]
We might also implement a general purpose split_when function and use that rather than functools.reduce.
def split_when(lst, pred):
if len(lst) == 0: return
last = lst[0]
lst2 = [last]
for x in lst[1:]:
if pred(last, x):
yield lst2
lst2 = [x]
last = x
else:
lst2.append(x)
last = x
if len(lst2) > 0:
yield lst2
lst2 = list(split_when(lst, lambda a, b: a - b > 1))
# [[68, 67], [53], [21, 20, 19], [9], [7], [1, 0]]

Clustering a list with nearest values without sorting

I have a list like this
tst = [1,3,4,6,8,22,24,25,26,67,68,70,72,0,0,0,0,0,0,0,4,5,6,36,38,36,31]
I want to group the elements from above list into separate groups/lists based on the difference between the consecutive elements in the list (differing by 1 or 2 or 3).
I have tried following code
def slice_when(predicate, iterable):
i, x, size = 0, 0, len(iterable)
while i < size-1:
if predicate(iterable[i], iterable[i+1]):
yield iterable[x:i+1]
x = i + 1
i += 1
yield iterable[x:size]
tst = [1,3,4,6,8,22,24,25,26,67,68,70,72,0,0,0,0,0,0,0,4,5,6,36,38,36,31]
slices = slice_when(lambda x,y: (y - x > 2), tst)
whola=(list(slices))
I got this results
[[1, 3, 4, 6, 8], [22, 24, 25, 26], [67, 68, 70, 72, 0, 0, 0, 0, 0, 0, 0], [4, 5, 6], [36, 38, 36, 31]]
In 3rd list it doesn't separate the sequence of zeros into another list. Any kind of help highly appreciate. Thank you
I guess this is what you want?
tst = [1,3,4,6,8,22,24,25,26,67,68,70,72,0,0,0,0,0,0,0,4,5,6,36,38,36,31]
slices = slice_when(lambda x,y: (abs(y - x) > 2), tst) # Use abs!
whola=(list(slices))
print(whola)

Trying to code bi-Directional Fibonacci Sequence i.e. even negative numbers

With suggestions, trail and errors; i have iterated the code. However, i still have query:
Current Result : [1, -1, 2, -3, 5, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
Expected & Accurate Result: [5, -3, 2, -1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
value has correct sequence. each value corresponds to the range value.
However, - value are reversed. (-1) position has 5 & (-5) position has 1. How do i solve it?
Also, if i try bi_fibonacci(5,10):
Ans: [0, 1, 1, 2, 3, 5] - it consider len of the range. irrespective of values.
I would like it to show: [8, 13, 21, 34, 55] - The actual answer.
How do i solve it?
Thanks in advance.
def bi_fibonacci(num1, num2):
a = 1
b = -1
for item in range(num1, num2+1):
if item < 0:
yield a
temp = a
a = b
b = temp - b
a = 0
b = 1
for item in range(num1,num2+1):
if item > -1:
yield a
temp = a
a = b
b = temp + b
fibo_seq = [x for x in bi_fibonacci(-8,8)]
print(fibo_seq)
print(len(fibo_seq))
First, I believe you need a stack for the negative fibonacci sequence. Either an explicit stack (e.g. a list) or an implicit one (i.e. recursion.) Second, you need to do careful bookkeeping on this problem. Consider these three cases:
sequence = bi_fibonacci(-10, -5)
sequence = bi_fibonacci(-10, 10)
sequence = bi_fibonacci(5, 10)
You want to handle all three correctly but without making any of them a special case. Below is my solution using an explicit stack
# ..., −8, 5, −3, 2, −1, 1, 0, 1, 1, 2, 3, 5, 8, ...
def bi_fibonacci(num1, num2):
n = -1
a = 1
b = 0
stack = []
while n >= num1:
if n <= num2:
stack.append(a)
a, b = b - a, a
n -= 1
if stack:
yield from reversed(stack)
n = 0
a = 0
b = 1
while n <= num2:
if n >= num1:
yield a
a, b = b, a + b
n += 1
sequence = bi_fibonacci(-10, -5)
print(*sequence, sep=', ')
sequence = bi_fibonacci(-10, 10)
print(*sequence, sep=', ')
sequence = bi_fibonacci(5, 10)
print(*sequence, sep=', ')
OUTPUT
> python3 test.py
-55, 34, -21, 13, -8, 5
-55, 34, -21, 13, -8, 5, -3, 2, -1, 1, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55
5, 8, 13, 21, 34, 55
>

Replace values of elements in a list on Python

I have a random list which is;
newList = [2, 44, 28, 32, 46, 31]
I have a random value which has to be in this way;
{1:8, 2:7, 3:6, 4:5, 5:4, 6:3, 7:2, 8:1}
So if a value in the list is 4, it needs to replace with 5 If a value in the list is 2, it needs to replace with 7 for each one.
when I try this code:
newList1 = list(map(int, newList))
nnList = []
for i in newList1:
i = str(i).split(',')
for y in list(map(str, i)):
for n in y:
print(n)
if n == '1':
n = 8
elif n == '2':
n = 7
elif n == '6':
n = 3
elif n == '3':
n = 6
elif n == '4':
n = 5
elif n == '5':
n = 4
elif n == '7':
n = 2
elif n == '8':
n = 1
nnList.append(n)
print(nnList)
When I run this code, I have this output: [7, 5, 5, 7, 1, 6, 7, 5, 3, 6, 8]
But I need to get in this way: [7, 55, 71, 67, 53, 68]
How can I do it?
Here is what you can do:
newList = [2, 44, 28, 32, 46, 31]
d = {1:8, 2:7, 3:6, 4:5, 5:4, 6:3, 7:2, 8:1}
l = [int(''.join([str(d[int(g)]) for g in str(n)])) for n in newList]
print(l)
Output:
[7, 55, 71, 67, 53, 68]
The short answer is: you need to combine the new digits for a number into a single value before adding it to your list.
The longer answer is that you are doing far too many conversions. You don't need to convert the entire list of int values to a single string, and newList is already a list of int values; you don't need to build newList1.
nnList = []
for i in newList:
newNum = int(''.join(str(9-int(x)) for x in str(i)))
nnList.append(newNum)
A more basic approach using if else and looping can be,
l1= [2, 44, 28, 32, 46, 31]
dict1={1:8, 2:7, 3:6, 4:5, 5:4, 6:3, 7:2, 8:1}
l2=[]
for n,i in enumerate(l1):
str1=str(i)
if len(str1)>1:
str2=""
for j in str1:
if int(j) in dict1:
str2+=str(dict1[int(j)])
l1[n]=int(str2)
else:
if i in dict1:
l1[n]=dict1[i]
print(l1)
output:
[7, 55, 71, 67, 53, 68]
newlist = [2, 44, 28, 32, 46, 31]
repl = {1:8, 2:7, 3:6, 4:5, 5:4, 6:3, 7:2, 8:1}
for i, el in enumerate(newlist):
newlist[i] = repl.get(el, newlist[i])
print(newlist)
repl.get(el, newlist[1]) means: try to find el in the repl dictionary, if it is not in the dictionary, use newlist[i] (the original value) instead, thus replacing the value by itself.

Count total number of occurrences of given list of integers in another

How do I count the number of times the same integer occurs?
My code so far:
def searchAlgorithm (target, array):
i = 0 #iterating through elements of target list
q = 0 #iterating through lists sublists via indexes
while q < 4:
x = 0 #counting number of matches
for i in target:
if i in array[q]:
x += 1
else:
x == 0
print(x)
q += 1
a = [8, 12, 14, 26, 27, 28]
b = [[4, 12, 17, 26, 30, 45], [8, 12, 19, 24, 33, 47], [3, 10, 14, 31, 39, 41], [4, 12, 14, 26, 30, 45]]
searchAlgorithm(a, b)
The output of this is:
2
2
1
3
What I want to achieve is counting the number of times '1', '2' '3' matches occurs.
I have tried:
v = 0
if searchAlgorithm(a, b) == 2:
v += 1
print(v)
But that results in 0
You can use intersection of sets to find elements that are common in both lists. Then you can get the length of the sets. Here is how it looks:
num_common_elements = (len(set(a).intersection(i)) for i in b)
You can then iterate over the generator num_common_elements to use the values. Or you can cast it to a list to see the results:
print(list(num_common_elements))
[Out]: [2, 2, 1, 3]
If you want to implement the intersection functionality yourself, you can use the sum method to implement your own version. This is equivalent to doing len(set(x).intersection(set(y))
sum(i in y for i in x)
This works because it generates values such as [True, False, False, True, True] representing where the values in the first list are present in the second list. The sum method then treats the Trues as 1s and Falses as 0s, thus giving you the size of the intersection set
This is based on what I understand from your question. Probably you are looking for this:
from collections import Counter
def searchAlgorithm (target, array):
i = 0 #iterating through elements of target list
q = 0 #iterating through lists sublists via indexes
lst = []
while q < 4:
x = 0 #counting number of matches
for i in target:
if i in array[q]:
x += 1
else:
x == 0
lst.append(x)
q += 1
print(Counter(lst))
a = [8, 12, 14, 26, 27, 28]
b = [[4, 12, 17, 26, 30, 45], [8, 12, 19, 24, 33, 47], [3, 10, 14, 31, 39, 41], [4, 12, 14, 26, 30, 45]]
searchAlgorithm(a, b)
# Counter({2: 2, 1: 1, 3: 1})
Thanks to some for their helpful feedback, I have since come up a more simplified solution that does exactly what I want.
By storing the results of the matches in a list, I can then return the list out of the searchAlgorithm function and simple use .count() to count all the matches of a specific number within the list.
def searchAlgorithm (target, array):
i = 0
q = 0
results = []
while q < 4:
x = 0 #counting number of matches
for i in target:
if i in array[q]:
x += 1
else:
x == 0
results.append(x)
q += 1
return results
a = [8, 12, 14, 26, 27, 28]
b = [[4, 12, 17, 26, 30, 45], [8, 12, 19, 24, 33, 47], [3, 10, 14, 31, 39, 41], [4, 12, 14, 26, 30, 45]]
searchAlgorithm(a, b)
d2 = (searchAlgorithm(winNum, lotto).count(2))

Categories

Resources