6

Q: A run is a sequence of adjacent repeated values. Given a list, write a function to determine the length of the longest run. For example, for the sequence [1, 2, 5, 5, 3, 1, 2, 4, 3, 2, 2, 2, 2, 3, 6, 5, 5, 6, 3, 1], the longest run is 4.

I am having trouble with this, I've written a code that finds the longest run consist of the number '2' but have yet to get the length of the run which is 4.

Here is my code so far (i've commented out a part that i was working on but don't pay attention to it):

# longestrun.py
#   A function to determine the length of the longest run
#   A run is a sequence of adjacent repeated values.

def longestrun(myList):
    result = None
    prev = None
    size = 0
    max_size = 0


    for i in myList:
        if i == prev:
            size += 1
            if size > max_size:
                result = i
                max_size = size
        else:
            size = 0
        prev = i
    return result



def main():
    print("This program finds the length of the longest run within a given list.")
    print("A run is a sequence of adjacent repeated values.")

    myString = input("Please enter a list of objects (numbers, words, etc.) separated by
    commas: ")
    myList = myString.split(',')

    longest_run = longestrun(myList)

    print(">>>", longest_run, "<<<")

main()

Help please!!! :(((

DSM
  • 342,061
  • 65
  • 592
  • 494
user3386327
  • 63
  • 1
  • 1
  • 6
  • You're just returning the value; return both the value and the count: `return (result, max_size)` and you should be good. – vanza Mar 06 '14 at 03:19
  • duplicate https://stackoverflow.com/questions/22214086/python-a-program-to-find-the-length-of-the-longest-run-in-a-given-list – pylang Feb 21 '18 at 03:59

6 Answers6

16

You can do this in one line using itertools.groupby:

import itertools
max(sum(1 for _ in l) for n, l in itertools.groupby(lst))
David Robinson
  • 77,383
  • 16
  • 167
  • 187
0

This should work if you do not want to use itertools and imports.

a=[1, 2, 5, 5, 3, 1, 2, 4, 3, 2, 2, 2, 2, 3, 6, 5, 5, 6, 3, 1]

def longestrun(myList):
    result = None
    prev = None
    size = 0
    max_size = 0


    for i in myList:
        if i == prev:
            print (i)
            size += 1
            if size > max_size:
                print ('*******  '+ str(max_size))
                max_size = size 
        else:
            size = 0
        prev = i
    print (max_size+1)    
    return max_size+1


longestrun(a)
Reverend_Dude
  • 148
  • 1
  • 10
  • This doesn't work if the result is not contained in the list. It should be able to return "0", instead it will return 1 at least (max_size + 1) – Francesco Sep 09 '14 at 12:55
  • If you read the question, it is fair to assume that you are not given an empty list. and if you are that is not a hard fix. appreciate your insight though. – Reverend_Dude Sep 09 '14 at 17:01
  • it's not that you can assume not to have an empty list. It's that you are assuming that the minimum possible longest run is at least 1 (that is: you assume that there will be a non empty list which will contain at least 1 instance of the item you are looking for). – Francesco Sep 15 '14 at 07:12
  • Ahh. yes if the list is not empty and has only one instance of each item i.e. fib seq, natural nums etc. but that is actually covered in this code since the size would be 0, the initial value of max_size and then have +1 at the very end... does that answer your question? furthermore the code searches for each item atleast once. – Reverend_Dude Sep 16 '14 at 23:03
0

Just another way of doing it:

def longestrun(myList):
    sett = set()
    size = 1
    for ind, elm in enumerate(myList):
        if ind > 0:
            if elm == myList[ind - 1]:
                size += 1
            else:
                sett.update([size])
                size = 1
    sett.update([size])
    return max(sett)

myList = [1, 2, 5, 5, 3, 1, 2, 4, 3, 2, 2, 2, 2, 3, 6, 5, 5, 6, 3, 1]
print longestrun(myList)
James Sapam
  • 16,036
  • 12
  • 50
  • 73
0
def longestrun(myList):
    size = 1
    max_size = 0
    for i in range(len(myList)-1):
        if myList[i+1] = myList[i]:
            size += 1
        else: 
            size = 1
        if max_size<size:
            max_size = size
    return size 

Remove the .split() from myList in main() and you're good to go with this.

Nordle
  • 2,915
  • 3
  • 16
  • 34
0
def getSublists(L,n):
    outL=[]
    for i in range(0,len(L)-n+1):
        outL.append(L[i:i+n])
    return outL


def longestRun(L):
    for n in range(len(L), 0, -1):
        temp=getSublists(L,n)
        for subL in temp:
            if subL==sorted(subL):
                return len(subL)
Matthew Moisen
  • 16,701
  • 27
  • 128
  • 231
sagayev
  • 25
  • 6
0

As an update to David Robinson's answer, it is now (Python 3.4) possible to return 0 on an empty sequence (instead of raising ValueError):

import itertools
max((sum(1 for _ in l) for n, l in itertools.groupby(lst)), default=0)
Aristide
  • 3,606
  • 2
  • 30
  • 50
  • 1
    You don't need a list here. Why not feed a generator comprehension, i.e. replace `[]` by `()`? – jpp Oct 23 '18 at 09:28
  • It's a syntaxic requirement. Otherwise, you get `SyntaxError: Generator expression must be parenthesized if not sole argument`. – Aristide Oct 24 '18 at 08:09