Profilo di primitivo

Nome primitivo
Indirizzo email n/a
Messaggi2
  • Re: stampare due sequenze di numeri di cui una incrementata
    Forum >> Principianti
    uhm... se hai voglia di leggere qualcosa di lungo ma che potrebbe valere la pena...


    Questi incasinamenti con il "for" li vedo spesso, e ho la sensazione che dipendano dal fatto che il principiante di solito non ha un'idea chiara di come funziona davvero "for".


    La cosa importante da capire è che "for" non "produce" proprio niente, non "crea" una sequenza di numeri (o altro). Si limita a ciclare su una sequenza che esiste già in partenza, e non la può modificare.


    (E qui apro una parentesi perché ho un sospetto... "range" invece sì che "produce" una sequenza di numeri, lui... non sarà che i manuali spiegano sempre "for" in connessione con "range", e il principiante confonde le due cose? Bisognerebbe smetterla di spiegare "for" in connessione con "range", credo. Ma anche qui, non è difficile capire il punto: quando tu scrivi "for x in range(...)", la prima cosa che succede è che "range(...)" ti produce una sequenza; dopo di che, "for" cicla su quella sequenza... ma ormai la sequenza è prodotta, e "for" non può modificarla... "for", di suo, non "produce" niente.)

    Torniamo al nostro "for". Quando tu scrivi
    for a in (1, 2, 3, 4):
        # qualcosa
    
    il tuo "for" si limita a ciclare su "(1, 2, 3, 4)" e assegnare alla variabile "a", di volta in volta, il valore "1", poi "2", poi "3", e infine "4". Ma il lavoro di "for" si ferma lì. La sequenza è già stabilita in partenza, e "for" non può modificarla: può solo prendere atto della sequenza che gli viene sottoposta, e ciclarci sopra. Poi ovviamente, tu puoi lavorare con la tua variabile "a" e farci delle operazioni sopra, che "producono" nuovi valori... questo è senz'altro possibile:
    for a in (1, 2, 3, 4): 
        square = a ** 2
        print(square)
    
    ma come vedi il lavoro di "produzione" di nuovi valori non è fatto dal "for", ma dal codice che scrivi dentro.


    Ora, se il tuo problema è produrre una sequenza di numeri come vuoi tu, allora concettualmente "for" non può aiutarti in questo compito... perché appunto "for" di per sé non produce proprio niente. Caso mai, "for" potrebbe esserti utile alla fine, per ciclare sugli elementi della sequenza "giusta", che avrai prodotto in qualche altro modo, e stamparli in modo ordinato, uno per volta. Ma prima dovresti trovare il modo di procurarti la sequenza giusta.


    Ovviamente, nel tuo caso, la sequenza giusta non è facilissima da creare... in modo tale che poi "for" possa tranquillamente ciclarci sopra, a cose fatte. In effetti bisogna creare due sequenze separate, ma qui ecco la difficoltà che hai incontrato... "for" cicla su *una* sequenza per volta, non su due o più sequenze allo stesso tempo. E provare ad annidare i "for", come hai visto, produce solo un gran mal di testa.


    Ora, a questo punto probabilmente ci sono delle considerazioni pratiche... immagino che questo sia un esercizio, che ti è stato assegnato da un corso, da un prof, qualcuno... e ovviamente ti sarà stato detto "usa il for! usa il for! il for!!!!!"... magari da un prof o da un corso che non ha spiegato (o forse capito!?) il for in maniera corretta. Naturalmente c'è il modo di risolvere il problema con il "for", figuriamoci. Tuttavia il vero problema è produrre la sequenza giusta... il modo canonico in python consiste nel produrre due sequenze (nel tuo caso, con "range") e poi "cucirle insieme" usando la funzione "zip"... che appunto prende due (o più) sequenze diverse ed emette una sola sequenza di *coppie* (o di terne, etc.)... E a questo punto puoi dare questa sequenza di coppie in pasto a "for" per ciclare in modo normale... Ma tutto questo richiede di conoscere "zip", di sapere come funziona, di averlo già visto in pratica... è piuttosto contro-intuitivo a dire il vero.
    In alternativa, l'algoritmo da usare è piuttosto laborioso (e contro-intuitivo)... puoi provare a ragionarci sopra, ma non è la cosa più facile del mondo, se non sei abituato. Si basa sul fatto che le due sequenze (chiamiamole A e B) che tu devi generare per prima cosa (con "range", per esempio) avranno lo stesso numero di elementi. Il tuo compito è scrivere il primo elemento di A accanto al primo elemento di B, poi il secondo di A accanto al secondo di B, e così via. Quindi puoi ragionare in termini di *indici*, invece che di elementi. Crei una terza sequenza (sempre con range, ovviamente) degli indici delle due liste (da zero a nove, suppongo), e usi "for" per ciclare su *questa* terza sequenza, invece che sulle due originarie... e a ogni passaggio scrivi l'elemento i-esimo della sequenza A accanto all'elemento i-esimo corrispondente della sequenza B. Ovvero:
    a = range(1, 11) # e NON range(1, 10)... come comunque scopriresti da solo...
    b = range(....) # come devi ancora scoprire... qualcosa che produca la sequenza 1, 5, 9, 13....
    indexes = range(10) # come credo che non farai fatica a scoprire
    # indexes = range(len(a)), come sarebbe meglio a dire il vero... se ti viene in mente
    for i in indexes:
        print(completa tu...)
    
    Tutto questo è piuttosto difficile da trovare da soli, se non si ha pratica (e se non si è capito che cosa fa davvero "for").


    Onestamente, quando il problema è "produrre" qualcosa, io penso che dal punto di vista di un principiante sia molto più naturale dimenticarsi il "for", e usare invece un semplice ciclo "while", con delle variabili che si incrementano man mano di quello che serve. Nel tuo caso, sarebbe qualcosa come:
    ho una variabile a impostata inizialmente a 1
    ho una variabile b impostata inizialmente a 1
    while a <= 10:
        scrivo a e b accanto # la prima iterazione mi darà quindi "1 1"
        incremento a di 1
        incremento b di 4
    
    Non è più semplice da progettare, una cosa del genere, dal punto di vista di un principiante?

    (Più che altro queste sono riflessioni sulla didattica di python... credo che sarebbe più produttivo proporre esercizi che richiedono l'uso di strumenti "naturali" per il problema in esame... se vuoi dare un esercizio sul "for", inventa una situazione dove l'uso del "for" venga naturale, non una dove sia forzato... mah.)



    Ciao Ric che dire .. grazie mille per la risposta molto esaustiva e dettagliata che mi hai fornito

    Con il while che mi hai consigliato ho risolto in modo semplice e pensare che mi stavo impazzendo con il "for" per senza niente
    Questi incasinamenti con il "for" li vedo spesso, e ho la sensazione che dipendano dal fatto che il principiante di solito non ha un'idea chiara di come funziona davvero "for".



    Infatti questo è stato proprio il mio caso :-)




    Ora, a questo punto probabilmente ci sono delle considerazioni pratiche... immagino che questo sia un esercizio, che ti è stato assegnato da un corso, da un prof, qualcuno... e ovviamente ti sarà stato detto "usa il for! usa il for! il for!!!!!"... magari da un prof o da un corso che non ha spiegato (o forse capito!?) il for in maniera corretta




    No nessun corso.. sono autodidatta e sto iniziando da poco..mi ero buttato io sul for perchè avevo visto alcuni esempi googlando con il for simili a ciò che mi serviva ... sbagliando ovviamente.




    Grazie di nuovo,

    Riccardo
  • stampare due sequenze di numeri di cui una incrementata
    Forum >> Principianti
    Salve a tutti
    da poco sto studiando python e sono nuovo anche nel mondo della programmazione

    Vorrei scrivere un semplice codice che mi stampi due sequenze di numeri, una costituita da 1,2,3,4,..n la seconda 1,5,9,13,...m che sia quindi costituita da incrementi di 4

    L'output che vorrei ottenere in sostanza è questo:




    1 1

    2 5

    3 9

    4 13

    5 17

    e cosi via




    Ho provato con un ciclo for annidato, che riporto sotto, ma il risultato non è quello desiderato




    numeri1 = range(1,10)

    numeri2 = range(1,10,4)

    for elemento_1 in numeri1:

    for elemento_2 in numeri2:

    if elemento_1 <= elemento_2:

    print (elemento_1, elemento_2)




    Quale modifica si potrebbe apportare a questo codice per ottenere il risultato corretto?

    E' la strada giusta quella di utilizzare un ciclo for annidato oppure sto sbagliando approccio?

    Grazie

    Riccardo