how to grab next-in-line integers from list python - 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]]

Related

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.

Indices of the N smallest elements of a list

i am trying to find 3 lowest number from a list and using those indexes to find corresponding value from another list.
this is an example of what i have tried
a = [12, 83, 22, 30, 57, 32, 88, 46, 20, 26, 78, 65, 45, 56, 74]
b = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']
lowest = lowest2 = lowest3 = max(a)
indexes = []
for i in range(0,len(a)):
if a[i] < lowest :
lowest = a[i]
print(b[i])
elif a[i] < lowest2 and a[i] > lowest:
lowest2 = a[i]
print(b[i])
elif a[i] < lowest3 and a[i] > lowest2:
lowest3 = a[i]
print(b[i])
print(lowest,lowest2,lowest3)
i can only supposed to use anaconda library and no this is not assignment this is a very small part of a program i have been trying to do.
output: a
b
c
d
i
j
12 20 26
What you can do is sort the list a and return it's index values,
>>> a = [12, 83, 22, 30, 57, 32, 88, 46, 20, 26, 78, 65, 45, 56, 74]
>>> n_min_values = 3
>>> sorted(range(len(a)), key=lambda k: a[k])[:n_min_values]
[0, 8, 2] # index values
and iterate through this index values list to get corresponding values from list b,
>>> b = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o']
>>> for i in sorted(range(len(a)), key=lambda k: a[k])[:n_min_values ]:
print(b[i])
a
i
c
OR
Using list comprehesion,
>>> [b[i] for i in sorted(range(len(a)), key=lambda k: a[k])[:n_min_values ]]
['a', 'i', 'c'] # your output
Heaps are good at doing this sort of thing, especially if the order of the smallest items isn't important.
Here's a small example using heapq.nsmallest on a with its zipped indices.
from heapq import nsmallest
from operator import itemgetter
n = 3
idx, _ = zip(*nsmallest(n, enumerate(a), key=itemgetter(1)))
idx
# (0, 8, 2)
[b[i] for i in idx] # your result
# ['a', 'i', 'c']

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))

Python: comparing three lists and not storing the same number twice

I have three lists:
list1 = [10, 20, 30]
list2 = [22, 19, 32]
list3 = [18, 21, 28]
I want to filter each list so that I remove a number that is not within 5 digits to another number in both the other two lists. However, I don't want any number being used twice. Here's my code:
output1 = []
output2 = []
output3 = []
for i, valuei in enumerate(list1):
for j, valuej in enumerate(list2):
for k, valuek in enumerate(list3):
delta1_2 = list1[i] - list2[j]
delta2_3 = list2[j] - list3[k]
if abs(delta1_2) < 5 and abs(delta2_3) < 5:
output1.append(valuei)
output2.append(valuej)
output3.append(valuek)
k=k+1
break
else:
continue
print(output1, output2, output3)
However, my output looks like this:
[20, 20, 30] [22, 19, 32] [18, 18, 28]
I want it to come out like this (I want "20" to be used only once and then move on to "30" in list1):
[20, 30] [22, 32] [18, 28]
Use the 'set' funtion for it:
output1 = []
output2 = []
output3 = []
for i, valuei in enumerate(list1):
for j, valuej in enumerate(list2):
for k, valuek in enumerate(list3):
delta1_2 = list1[i] - list2[j]
delta2_3 = list2[j] - list3[k]
if abs(delta1_2) < 5 and abs(delta2_3) < 5:
output1.append(valuei)
output2.append(valuej)
output3.append(valuek)
k=k+1
break
else:
continue
print(set(output1), set(output2), set(output3))
What you're asking does not match your examples...
def within(x, n, ys):
return any(abs(x - y) < n for y in ys)
def filter(list_in, list_to_compare):
return [x for x in list_in if within(x, 5, list_to_compare)]
For your inputs:
list1 = [10, 20, 30]
list2 = [22, 19, 32]
list3 = [18, 21, 28]
print(filter(list1, list2 + list3))
print(filter(list2, list1 + list3))
print(filter(list3, list1 + list2))
prints:
[20, 30]
[22, 19, 32]
[18, 21, 28]
19 and 21 are within 5 from 20 from list1, so they should not be filtered out.
Much credit to my friend for solving this.
list1 = [10, 20, 30]
list2 = [22, 19, 32]
list3 = [18, 21, 28]
output1 = []
output2 = []
output3 = []
keepGoing = True
matchFound = False
while(keepGoing):
matchFound = False
for i, valuei in enumerate(list1):
if(matchFound):
break
else:
for j, valuej in enumerate(list2):
if(matchFound):
break
else:
for k, valuek in enumerate(list3):
delta1_2 = list1[i] - list2[j]
delta2_3 = list2[j] - list3[k]
if abs(delta1_2) < 5 and abs(delta2_3) < 5:
matchFound = True
output1.append(list1[i])
output2.append(list2[j])
output3.append(list3[k])
list1 = list1[i+1:]
list2 = list2[j+1:]
list3 = list3[k+1:]
if not list1 or not list2 or not list3:
keepGoing = False
break
print((output1), (output2), (output3))
Output:
[20,30] [22,32] [18,28]

IndexError: list index out of range - throwing error in Python?

a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for i in a:
if a[i] % 2 == 0 :
l.append(a[i])
The code above keeps throwing the error - "IndexError: list index out of range"
I cannot understand what to do ?
When you perform for i in a you are iterating over the elements of a, not the indices!
You are trying to access: a[1] and then a[4] and then a[9] and then a[16] -> Which is the one that is causing the IndexError.
If you want to iterate only over the indices try:
>>> for i in range(len(a)):
if a[i] % 2 == 0 :
l.append(a[i])
>>> print (l)
[4, 16, 36, 64, 100]
If you need both the value and index use for index, value in enumerate(a):.
When you are iterating over a, you are looking at the value rather than the position of that value in the list.
You could use just the value like so:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for val in a:
if val % 2 == 0 :
l.append(val)
Or alternately, if you need both the position and the value then you can use the enumerate function, like so:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for pos, val in enumerate(a):
if a[pos] % 2 == 0 :
l.append(a[pos])
There are some ways:
for e in a:
if e % 2 == 0 :
l.append(e)
or
for i in range(len(a)):
if a[i] % 2 == 0 :
l.append(a[i])
or
for i, e in enumerate(a):
if e % 2 == 0 :
l.append(e)
or
for i, e in enumerate(a):
if a[i] % 2 == 0 :
l.append(a[i])
You could use list comprehension for that:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l = [i for i in a if i%2 == 0]
print(l)
[4, 16, 36, 64, 100]
List comprehesions can be used to make it one-liner
l=[x for x in a if x%2==0]
And as stated in ather answers your problem is that you are using list item as its indexes.
You can use filter for your task:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
print filter(lambda x: x % 2 == 0, a)
as in other answers, i takes the values from a, which are [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
in the loop when i takes the value "16", a[i] will be out of range!! (16 > len(a))
for debugging i always suggest printing...
in this case if you print the value ofi in the loop, you will find the problem yourself
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for i in a:
if a[i] % 2 == 0 :
l.append(a[i])
...
if a[1] % 2 == 0:
...
if a[4] % 2 == 0:
...
if a[9] % 2 == 0:
...
if a[16] % 2 == 0:
index error, because the biggest index is 9 in array a...
so u have to use this:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for i in a:
if i % 2 == 0 :
l.append(i)
or this example:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= []
for i in a:
if i % 2 == 0 :
l.append(i)
or the 1 line solution:
a = [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
l= [x for x in a if x%2 == 0]

Categories

Resources