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
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
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).
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?
Jag är också nyfiken.
Jag postar min lösning efter att KriAno postar sin.
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 itemgetterdef 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))
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.)
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 = [] # 1return 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!
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 itemgetterdef 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 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 = [] # 1return 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?
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)
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!! :)
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.