16 svar
317 visningar
KriAno är nöjd med hjälpen
KriAno 434
Postad: 2 nov 2019 21:37

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 9326
Postad: 2 nov 2019 22:11

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 9326
Postad: 3 nov 2019 22:35

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 7 – Fd. Medlem
Postad: 4 nov 2019 19:17

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)

Lindehaven 820 – Lärare
Postad: 7 nov 2019 10:10

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.

Lindehaven 820 – Lärare
Postad: 20 nov 2019 21:01

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

Dr. G 9326
Postad: 20 nov 2019 21:06

Jag är också nyfiken.

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

KriAno 434
Postad: 22 nov 2019 18:35
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.  

Lindehaven 820 – Lärare
Postad: 24 nov 2019 01:25

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 28468
Postad: 24 nov 2019 08:56 Redigerad: 24 nov 2019 09:00

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 434
Postad: 24 nov 2019 22:04
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 434
Postad: 24 nov 2019 22:08
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 :)

Lindehaven 820 – Lärare
Postad: 24 nov 2019 23:57
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 434
Postad: 25 nov 2019 14:12
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 28468
Postad: 25 nov 2019 14:50

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 434
Postad: 25 nov 2019 16:13
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 28468
Postad: 25 nov 2019 16:46

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