Lista sumowania

meiji
  • Rejestracja:ponad 6 lat
  • Ostatnio:około 6 lat
  • Lokalizacja:Mysłowice
  • Postów:12
0

Hej, mam pytanie odnośnie działania pętli tworzącej listę sum dwóch pierwszych elementów z listy, np. 1+2, 2+3, 3+4 ... itd.

Przykładowo, z listy [1, 2, 3, 4, 8, 12] chciałbym uzyskać listę [3, 5, 7, 12, 20].
Napisałem prosty szkielet, ale nie wykonuje on sumowania do końca. Zwraca listę [3, 5, 7]. Byłbym wdzięczny za podpowiedź, gdzie tkwi błąd.

Kopiuj
lista = [1, 2, 3, 4, 8, 12]
lista_sumowania = []
for elem in lista:
    print('Lista:', lista)
    lista_sumowania.append(lista[0] + lista[1])
    print('Sumowanie:', lista_sumowania)
    lista.pop(0)
print(lista_sumowania)
Guaz
  • Rejestracja:około 8 lat
  • Ostatnio:ponad 4 lata
  • Lokalizacja:Częstochowa
  • Postów:221
2

http://pythontutor.com/live.html#code=lista%20%3D%20%5B1,%202,%203,%204,%208,%2012%5D%0Alista_sumowania%20%3D%20%5B%5D%0Afor%20elem%20in%20lista%3A%0A%20%20%20%20print%28'Lista%3A',%20lista%29%0A%20%20%20%20lista_sumowania.append%28lista%5B0%5D%20%2B%20lista%5B1%5D%29%0A%20%20%20%20print%28'Sumowanie%3A',%20lista_sumowania%29%0A%20%20%20%20lista.pop%280%29%0Aprint%28lista_sumowania%29&cumulative=false&curInstr=13&heapPrimitives=nevernest&mode=display&origin=opt-live.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false
Podrzucam link jak chcesz zrozumieć co się dzieje źle w swoim programie :)

Mianowicie, nie polecam edytować długości listy na której pracuje for, ponieważ robią się takie 'kwiatki'.
Można to naprawić prosto, bez dużej ingerencji:

Kopiuj
lista = [1, 2, 3, 4, 8, 12]
lista_sumowania = []
for elem, elem_next in zip(lista, lista[1::]):
    print('Lista:', lista)
    lista_sumowania.append(elem + elem_next)
    print('Sumowanie:', lista_sumowania)
del(lista)
print(lista_sumowania)

Albo zrobić z pomocą while:

Kopiuj
lista = [1, 2, 3, 4, 8, 12]
lista_sumowania = []
while lista: #Czyli kiedy lista nie jest pusta:
    print('Lista:', lista)
    lista_sumowania.append(lista[0] + lista[1])
    print('Sumowanie:', lista_sumowania)
    lista.pop(0)
print(lista_sumowania)

Ten drugi sposób w sumie jest najlepszy, ponieważ i tak nie używasz zmiennej elem.

Jak już chcesz używać for'a gdzie faktycznie używasz wartości z niego:

Kopiuj
lista = [1, 2, 3, 4, 8, 12]
lista_sumowania = []
for indeks in range(len(lista)-1): #-1 bo ostatnim indeksem który potrzebujemy jest przedostatni
    print('Lista:', lista)
    lista_sumowania.append(lista[indeks] + lista[indeks+1]) #W ostatniej pętli tu dzięki -1 będzie przedostatni + ostatni. Inaczej byśmy mieli błąd
    print('Sumowanie:', lista_sumowania)
del(lista)
print(lista_sumowania)

Linux Mint
Arduino / Python 3.5.2
edytowany 2x, ostatnio: Guaz
CM
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 6 lat
  • Lokalizacja:Warszawa
  • Postów:118
0

Modyfikujesz listę po której iterujesz, stąd nieprzewidywalny na pierwszy rzut oka wynik. Rozwiązanie nie jest najpiękniejsze, ale zbliżone do tego co zaproponoałeś

Kopiuj
lista = [1, 2, 3, 4, 8, 12]
lista_sumowania = []
for i in range(len(lista) - 1):
    lista_sumowania.append(lista[i] + lista[i + 1])
print(lista_sumowania)

Trochę ładniejsza wersja

Kopiuj
lista_sumowania = [lista[i] + lista[i + 1] for i in range(len(lista) - 1)]
lion137
  • Rejestracja:około 8 lat
  • Ostatnio:około godziny
  • Postów:4936
2

Możesz próbować ręcznie, ale o Pythonie mówi się, że jest językiem z "batteries included". Do zabawy z takimi rzeczami polecam itertools, more itertools, oraz list comprehension. Z more itertools:

Kopiuj
import more_itertools

a_list =  [1, 2, 3, 4, 8, 12]

it = more_itertools.windowed(a_list, 2)

a_sum = [x + y for x, y in it]

print(a_sum) # -> [3, 5, 7, 12, 20]

https://more-itertools.readthedocs.io/en/latest/api.html#windowing
https://treyhunner.com/2018/06/how-to-make-an-iterator-in-python/
https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/


Zobacz pozostały 1 komentarz
Guaz
Jeśli tak, i znasz powód, byłbym wdzięczny za przybliżenie go, bo nie potrafię sobie ulogicznić ich zastosowania :)
lion137
for elem, elem_next in zip(lista, lista[1::]):, dalej: lista_sumowania.append(elem + elem_next). Nie nazwałbym tego jedna prosta komenda, ale OK. Właśnie po to są te biblioteki, żeby nie wymyślać koła na nowo tylko rozwiązać, każdy (prawie) problem z iterowaniem po listach. A użycie more itertools? Jak najbardziej: flatten, chunked...
Guaz
To tylko jak najmniejsza ingerencja w progam dla osoby początkującej, osobiście zrobiłbym to tak: [x + y for x, y in zip(lista[0:], lista[1:])] flatten i chunked... Faktycznie, ciekawe, do macierzy faktycznie by mi się dawniej przydało i nawet je zapamiętam. Ale tak i tak im dalej to czytam, tym bardziej mam wrażenie że to wymyślane na siłę :).
lion137
Trochę wymyślanie:), prawda, a Jakbyś miał mało, to jest jeszcze: https://toolz.readthedocs.io/en/latest/index.html oraz: https://boltons.readthedocs.io/en/latest/ :)
Guaz
O tym już nie słyszałem :D. Dzięki za link ^^

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.