Kun je me helpen met deze python-oefening?

Ik wil een functie schrijven die een lijst met getallen opneemt en de cumulatieve som retourneert; dat wil zeggen, een nieuwe lijst waarbij het eerste element de som is van de eerste i + 1-elementen uit de oorspronkelijke lijst. De cumulatieve som van [1, 2, 3] is bijvoorbeeld [1, 3, 6].

Hier is mijn code tot nu toe:

 def count(list1):
     x = 0
     total = 0
     while x < len(list1):
         if x == 0:
             total = list1[0]
             print total
             x = x +1
         else:
             total = list1[x] + list1[x -1]
             print total
             x = x + 1
     return total 

print count([1, 2, 3, 4, 7])

ECHTER werkt het niet.

Kun je me vertellen wat ik verkeerd doe? Ik heb hier al geruime tijd aan gewerkt.

heel erg bedankt!

Luke

3
itertools.accumulate
toegevoegd de auteur JBernardo, de bron
++ 1! naar @ DSM's commentaar .. mensen lijken dit te vaak te vergeten (en vaak hier in de buurt)
toegevoegd de auteur Levon, de bron
"Ik ben niet erg slim." Verwar gebrek aan ervaring met een gebrek aan intelligentie niet, of maak je zorgen dat we ze in verwarring brengen en voel daarom dat je je vooraf moet verontschuldigen omdat je iets niet begrijpt. Iedereen was ooit een beginner en mensen zijn niet geboren met Python. Nog niet in ieder geval..
toegevoegd de auteur DSM, de bron
Deze code is veel ingewikkelder dan het moet zijn: /
toegevoegd de auteur Ignacio Vazquez-Abrams, de bron
Bedankt voor die opmerking, DSM. Erg aardig van je.
toegevoegd de auteur Luke D, de bron

8 antwoord

Je zou het proces misschien een beetje overdenken. De logica hoeft niet echt opgesplitst te worden in dergelijke tests. Het deel dat u tot nu toe hebt, is de totaalteller, maar u moet alleen elke waarde in de lijst doorlopen. Niet een voorwaardelijke tijd doen, met if..se

Normaal zou ik niet alleen een antwoord geven, maar ik vind dat het meer voor u voordelig is om werkende code te zien dan om te proberen en te gaan door de extra en onnodige cruft die u tot nu toe hebt gehad.

def count(l):
    total = 0
    result = []
    for val in l:
        total += val
        result.append(total)
    return result

We gebruiken nog steeds de totale teller. En we maken een lege lijst voor onze resultaten. Maar alles wat we moeten doen, is elk item in de lijst doorlopen, toevoegen aan het totaal en elke keer de nieuwe waarde toevoegen. Er zijn geen conditionals en u hoeft zich geen zorgen te maken wanneer een while zal breken. Het is consistent dat je elk item in je oorspronkelijke lijst doorloopt.

9
toegevoegd
@LukeD: geen probleem! Ik dacht dat dit heel dicht in de buurt kwam van de terminologie die je tot nu toe waarschijnlijk hebt gekregen. Succes! Laat het me weten als je meer uitleg nodig hebt.
toegevoegd de auteur jdi, de bron
Ik zal meneer. Nogmaals bedankt, je was echt heel behulpzaam. Ik moest op een andere manier over de vraag nadenken, zoals je hebt gedaan. Dank je.
toegevoegd de auteur Luke D, de bron
Heel erg bedankt voor dit antwoord! Het is heel logisch! Ik lees het boek Think Python: Hoe te denken als een computerwetenschapper En ik heb al die dingen te ver geleerd. Heel erg bedankt! Je was echt heel behulpzaam!
toegevoegd de auteur Luke D, de bron

Hier voegt u de huidige index toe met de laatste en overschrijft u "totaal"

total = list1[x] + list1[x -1]

Ik denk dat je zoiets als dit wilt, het zal 31 teruggeven voor de onderstaande lijst.

def count(list1):
     x = 0
     total = 0
     while x < len(list1):
         total += list[x]
         print total
         x = x + 1
     return total

list = [1, 2, 4, 8, 16]
print count(list)
2
toegevoegd
U hebt een onderliggend probleem in de code in de vraag geïdentificeerd. Uw functie retourneert echter de som van de inhoud van de lijst, niet een nieuwe lijst met de cumulatieve bedragen zoals gevraagd in de vraag.
toegevoegd de auteur Blair, de bron
Bedankt voor je reactie! Het was erg behulpzaam! Bedankt!
toegevoegd de auteur Luke D, de bron

U hoeft deze functie niet te schrijven. Het staat in de itertools-module:

>>> list(itertools.accumulate([1,2,3]))
[1, 3, 6]
1
toegevoegd
@Levon de naam van de functie (accumuleren) spreekt voor zich. En aangezien het een generator is, heb ik er lijst op geplaatst
toegevoegd de auteur JBernardo, de bron
Ja, Ik weet dat .. gezien OP's problemen ik dacht dat het nuttig zou zijn geweest om een ​​minimale (bijv. 1 regel) uitleg aan hen te geven - dat is alles :) Niet iedereen is comfortabel met onze "pythonic "manieren ...
toegevoegd de auteur Levon, de bron
Ik denk dat een verklaring om met deze beknopte code mee te gaan, nuttig zou zijn
toegevoegd de auteur Levon, de bron

Een andere oplossing, one-liner, maar zeker werkend ( http://ideone.com/qtwh7 ), hoewel multi -line oplossingen zijn duidelijker over wat hier echt gebeurt:

data = [3, 7, 22, -3, 5, -23, 16]

result = reduce(lambda a, b: a+[a[-1]+b], data, [0])[1:]

print result
1
toegevoegd
@astynax: misschien heb je gelijk, maar het ziet er vreemd uit;) En welke orde van grootte is het, 7x of 76x sneller? ;) Je kunt echter op dezelfde manier proberen om map() te gebruiken. En het kan (zou?) Nog sneller zijn.
toegevoegd de auteur Tadeck, de bron
eerst - 7 keer sneller, tweede - 6 keer sneller. Met len ​​(data) == 10000: eerste - 45 keer sneller, tweede - 35 :)
toegevoegd de auteur astynax, de bron
mijn eerste (tweede) variant met len (data) == 1000 is 7 (6) keer sneller, en meer geheugenefficiënt :)
toegevoegd de auteur astynax, de bron
Dit kan gedaan worden zonder de aaneenschakeling: verminderen (lambda r, x: r.append (r [-1] + x) of r, data, [0]) [1:] of zelfs zonder de indexering verminderen (lambda (res, sum), x: (res.append (sum + x) of res, sum + x), data, ([], 0)) [0]
toegevoegd de auteur astynax, de bron

Een eenvoudige benadering kan zijn

>>> given_list = [1, 4, 5, 8]
>>> output_list = [sum(given_list[:num]) for num in range(len(given_list)+1)]
>>> output_list
[0, 1, 5, 10, 18]
>>> output_list[1:]
[1, 5, 10, 18]
>>> 

Kijk of dit voor een ander soort lijst werkt. Ik laat dat voor jou achter.

1
toegevoegd
Niets mis met het presenteren van deze oplossing als een alternatieve benadering, hoewel misschien de term "eenvoudig" niet het optimale woord was om dit in deze context van de vraag van OP te beschrijven :) .. nog steeds zeker Pythisch.
toegevoegd de auteur Levon, de bron
Ik schaam me ervoor om de oplossing op deze manier geprobeerd te hebben.
toegevoegd de auteur pyfunc, de bron
@ LukeD: En het gaat helemaal niet om slim zijn. Het gaat om leren, doorzettingsvermogen en hard werken. Ik denk dat we dat allemaal kunnen proberen. Met een beetje hulp van SO kan leren plezierig worden
toegevoegd de auteur pyfunc, de bron
@ LukeD: Er zijn veel echt leuke manieren om dingen in minder code te berekenen. Uiteindelijk kom je de lijstbegrippen tegen.
toegevoegd de auteur jdi, de bron
Dit is een heel gecompliceerde manier voor een beginner en kan het beeld niet van de OP krijgen.
toegevoegd de auteur jdi, de bron
Bedankt voor de suggestie, pyfunc. Het is een beetje te gecompliceerd voor mij, maar bedankt voor je hulp. Als ik slimmer was, weet ik zeker dat ik het beter zou begrijpen!
toegevoegd de auteur Luke D, de bron

U doet niet precies wat u wilt doen met totaal .

Waar u totaal aan instelt, is lijst [x] + lijst [x + 1] . Je wilt echt dat dit de som is van all vorige elementen en het huidige element.

Vervang totaal = lijst1 [x] + lijst1 [x-1] met totaal + = lijst1 [x] .

1
toegevoegd
Bedankt voor die suggestie! Ik heb het geprobeerd, maar het werkt niet. Maar het heeft definitief geholpen, en bedankt!
toegevoegd de auteur Luke D, de bron

Dit is de oplossing die ik bedacht:

def count(list1):
     total = 0
     old = 0
     for position, x in enumerate(list1):
         total = x + old
         old = x
         print total
     return


count([1,1,2,3,5,8,13])
1
toegevoegd
bedankt Jon voor het formatteren van dit =)
toegevoegd de auteur Ray, de bron

Ik deed dezelfde oefening, en wat volgt is mijn oplossing. Het gebruikt alleen de basismethode appendix en de operator slice lijst.

def accum(list):
    """Sequential accumulation of the original list"""
    result = []
    for i in range(len(list)):
        result.append(sum(list[:i+1]))
    return result
0
toegevoegd