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.

Asked By: Phil Gibson

||

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)
Answered By: Tim Roberts

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]
Answered By: Alexander

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]]
Answered By: Chris

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]
Answered By: Daniel Hao
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.