16 svar
225 visningar
KriAno är nöjd med hjälpen!
KriAno 365
Postad: 2 nov 2019

På varandra följande tal i en lista

Hej!

Kan man på något sätt se högsta antalet på varandra följande tal i en lista, och även se vilka talen är? 

T.ex. om man har en lista som ser ut såhär:

List=[182, 183, 548, 549, 550]

Då är ju det högsta antalet på varandra följande tal 3 och talen är 548, 549 och 550.

Väldigt tacksam för hjälp!

MVH KriAno

Dr. G Online 5472
Postad: 2 nov 2019

Gör en egen funktion som kollar detta. Loopa igenom listan och se för vilka index j som 

List[j + 1] == List[j] + 1

Dr. G Online 5472
Postad: 3 nov 2019

Hur gick det här?

Jag fulkodade ihop en funktion som löser detta med brute force. Sannolikt finns det en hel del genvägar med inbygda funktioner i Python (eller bara med snyggare kodning).

FreeCodeParty 33
Postad: 4 nov 2019

Här har du koden!

#!/usr/bin/env python3

mylist = [182, 183, 548, 549, 550]

mylist.sort()

index = len(mylist) - 3

newlist = mylist[index:]

print(newlist)

FreeCodeParty's kod funkar endast om det är tre tal och om de talen är de högsta i listan. Det blir uppenbart om man provar med exvis:

List=[12, 13, 14, 15, 548, 549, 550]

Dr. G har ett bättre tips.

Hur gick det med detta? Har du lyckats lösa uppgiften?

Dr. G Online 5472
Postad: 20 nov 2019

Jag är också nyfiken.

Jag postar min lösning efter att KriAno postar sin.

KriAno 365
Postad: 22 nov 2019
Dr. G skrev:

Jag är också nyfiken.

Jag postar min lösning efter att KriAno postar sin.

Hej igen!

Här ovan kan ni se min lösning. Dock så blir det lite problem när det är flera "7 på varandra följande tal". Eller det blir i alla fall inte så snyggt.  

Bra jobbat att få till ett korrekt svar KriAno. Provade själv och sökte lite hjälp från modulerna itertools och operator. Har inte använt itertools så mycket men där finns en del magi.

from itertools import groupby
from operator import itemgetter

def consequtive(x):
    c = []
    if x:
        for k, g in groupby(enumerate(x), lambda (i, y): i-y):
            c.append(map(itemgetter(1), g))
        c.sort(reverse=True, key=len)
        for i in range(len(c)-1, 0, -1):
            if len(c[i]) < len(c[0]):
                del c[i]
    return len(c[0]), c
   
mylist = [3,4,5,6,900,901,902,903,904,905,906,
          1,2,3,4,5,6,7,1,2,3,4,5,6,7]
print(consequtive(mylist))

Laguna 8982
Postad: 24 nov 2019 Redigerad: 24 nov 2019

Jag förenklade några rader:

 

def s(l):
    global listtal, copycat
    n = 1
    while n<len(l) and l[n]-l[0]==n:
        n+=1
    if len(l[:n]) == len(listtal):
        copycat.append(l[:n])
    elif len(l[:n]) > len(listtal):
        listtal = l[:n] # 3
        copycat = []  # 1

    return max(n,s(l[n:])) if l else 0

print(s(List))

if len(copycat)>0:  # 2
    listtal.extend(copycat)

print(listtal)

 

1) Det är renare (mer lättbegripligt) att bara sätta t.ex. copycat=[] om det är det man menar. Man måste bara säga med global att det är en global variabel.

2) Loopen för att hitta rätt k är onödig (och tänk om List har mer än 10000 element). Det räcker att testa att längden inte är 0.

3) Eftersom listtal sattes till tom lista precis innan kan vi gärna sätta listtal till rätt innehåll direkt, i stället för att använda extend.

Det finns fortfarande en konstighet i resultatet: om det innehåller flera sekvenser av samma längd så är elementen i den första inte inpackade i en lista. T.ex. [1,2,5,6] blir [1,2,[5,6]]. Resultatet är entydigt men opraktiskt.

Edit: Jag föreslår också att man inför en rad "s = l[:n]" före if-raden och sedan använder s där det går, så blir det mer lättläst. (Längre variabelnamn än 's' kan man förstås tänka sig.)

KriAno 365
Postad: 24 nov 2019
Laguna skrev:

Jag förenklade några rader:

 

def s(l):
    global listtal, copycat
    n = 1
    while n<len(l) and l[n]-l[0]==n:
        n+=1
    if len(l[:n]) == len(listtal):
        copycat.append(l[:n])
    elif len(l[:n]) > len(listtal):
        listtal = l[:n] # 3
        copycat = []  # 1

    return max(n,s(l[n:])) if l else 0

print(s(List))

if len(copycat)>0:  # 2
    listtal.extend(copycat)

print(listtal)

 

1) Det är renare (mer lättbegripligt) att bara sätta t.ex. copycat=[] om det är det man menar. Man måste bara säga med global att det är en global variabel.

2) Loopen för att hitta rätt k är onödig (och tänk om List har mer än 10000 element). Det räcker att testa att längden inte är 0.

3) Eftersom listtal sattes till tom lista precis innan kan vi gärna sätta listtal till rätt innehåll direkt, i stället för att använda extend.

Det finns fortfarande en konstighet i resultatet: om det innehåller flera sekvenser av samma längd så är elementen i den första inte inpackade i en lista. T.ex. [1,2,5,6] blir [1,2,[5,6]]. Resultatet är entydigt men opraktiskt.

Edit: Jag föreslår också att man inför en rad "s = l[:n]" före if-raden och sedan använder s där det går, så blir det mer lättläst. (Längre variabelnamn än 's' kan man förstås tänka sig.)

Ok tack så jättemycket! Men vad menas med global variabel? Har försökt väldigt länge med att få utskriften att bli snyggare så inte klamrarna "hamnar" bättre lyckas inte. Skulle uppskatta hjälp för att kunna lösa det! 

KriAno 365
Postad: 24 nov 2019
Lindehaven skrev:

Bra jobbat att få till ett korrekt svar KriAno. Provade själv och sökte lite hjälp från modulerna itertools och operator. Har inte använt itertools så mycket men där finns en del magi.

from itertools import groupby
from operator import itemgetter

def consequtive(x):
    c = []
    if x:
        for k, g in groupby(enumerate(x), lambda (i, y): i-y):
            c.append(map(itemgetter(1), g))
        c.sort(reverse=True, key=len)
        for i in range(len(c)-1, 0, -1):
            if len(c[i]) < len(c[0]):
                del c[i]
    return len(c[0]), c
   
mylist = [3,4,5,6,900,901,902,903,904,905,906,
          1,2,3,4,5,6,7,1,2,3,4,5,6,7]
print(consequtive(mylist))

Tack för svar! Ska kolla mer på detta sen, lär återkomma med frågor :)

KriAno skrev:

Ok tack så jättemycket! Men vad menas med global variabel? Har försökt väldigt länge med att få utskriften att bli snyggare så inte klamrarna "hamnar" bättre lyckas inte. Skulle uppskatta hjälp för att kunna lösa det! 

En global variabel kan användas varsomhelst i programmet, även inifrån funktioner. Jag rekommenderar alltid att aldrig använda globala variabler eftersom testning och felsökning försvåras betydligt med globala variabler.

KriAno 365
Postad: 25 nov 2019
KriAno skrev:
Laguna skrev:

Jag förenklade några rader:

 

def s(l):
    global listtal, copycat
    n = 1
    while n<len(l) and l[n]-l[0]==n:
        n+=1
    if len(l[:n]) == len(listtal):
        copycat.append(l[:n])
    elif len(l[:n]) > len(listtal):
        listtal = l[:n] # 3
        copycat = []  # 1

    return max(n,s(l[n:])) if l else 0

print(s(List))

if len(copycat)>0:  # 2
    listtal.extend(copycat)

print(listtal)

 

1) Det är renare (mer lättbegripligt) att bara sätta t.ex. copycat=[] om det är det man menar. Man måste bara säga med global att det är en global variabel.

2) Loopen för att hitta rätt k är onödig (och tänk om List har mer än 10000 element). Det räcker att testa att längden inte är 0.

3) Eftersom listtal sattes till tom lista precis innan kan vi gärna sätta listtal till rätt innehåll direkt, i stället för att använda extend.

Det finns fortfarande en konstighet i resultatet: om det innehåller flera sekvenser av samma längd så är elementen i den första inte inpackade i en lista. T.ex. [1,2,5,6] blir [1,2,[5,6]]. Resultatet är entydigt men opraktiskt.

Edit: Jag föreslår också att man inför en rad "s = l[:n]" före if-raden och sedan använder s där det går, så blir det mer lättläst. (Längre variabelnamn än 's' kan man förstås tänka sig.)

Ok tack så jättemycket! Men vad menas med global variabel? Har försökt väldigt länge med att få utskriften att bli snyggare så inte klamrarna "hamnar" bättre lyckas inte. Skulle uppskatta hjälp för att kunna lösa det! 

...menar att behöver hjälp med att snygga till utskriften så att klamrarna hamnar rätt, har någon något förslag? 

Laguna 8982
Postad: 25 nov 2019

listtal innehåller tydligen den första dellistan som man vill spara på. Då borde det bli rätt om man byter ut

 listtal.extend(copycat)

mot

 listtal = [listtal]
 listtal.extend(copycat)

KriAno 365
Postad: 25 nov 2019
Laguna skrev:

listtal innehåller tydligen den första dellistan som man vill spara på. Då borde det bli rätt om man byter ut

 listtal.extend(copycat)

mot

 listtal = [listtal]
 listtal.extend(copycat)

Tusen tack!! :)

Laguna 8982
Postad: 25 nov 2019

Om du vill fortsätta förfina din lösning så försök göra om den till en iterativ (med while) i stället för rekursiv (anropar sig själv).

Jag inbillar mig att något kan bli enklare då, men jag är inte säker.

Svara Avbryt
Close