how to grab next-in-line integers from list python
Question:
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.
Answers:
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)
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]
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]]
Alternatively, you prob. can do this way too:
# L is your list
extras = [x for x in L if x-1 in L]
print(extras) # [68, 21, 20, 1] # next in line...
# if ordering is not important, you could change to set(L) to speed up for a big list...
# This also adaptable to find true starts, if req. changes later.
starts = [x for x in L if x+1 not in L and x-1 in L]
# [68, 21, 1]
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.
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)
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]
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]]
Alternatively, you prob. can do this way too:
# L is your list
extras = [x for x in L if x-1 in L]
print(extras) # [68, 21, 20, 1] # next in line...
# if ordering is not important, you could change to set(L) to speed up for a big list...
# This also adaptable to find true starts, if req. changes later.
starts = [x for x in L if x+1 not in L and x-1 in L]
# [68, 21, 1]