Pagina 1 di 1

[Risolto] Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 18:58
da raffaele63
Ciao a tutti,
sto cercando di generare una sequenza numerica, da 1 a x numero, ma casuale e non ripetitiva.
Spiego: non voglio 1-2-3 ecc, e neanche 1-5-2-1-5 ecc. Ho provato con random. randint() e con random.randrange() ma non ottengo la numerazione che voglio.
Ho anche passato diverso tempo alla ricerca nel forum, di argomenti simili, ma non sono arrivato a niente (o forse non ho visto bene), quindi se già vi è stata una discussione simile per favore indicatemela, in alternativa chiedo aiuto e all'occorrenza posterò anche il codice.
Grazie mille.
Scusatemi, ma appena chiuso mi sono accorto di non aver scritto il linguaggio: Python versione 2.6
Il codice lo posto in risposta.

Re: Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 19:22
da Bianco95
Ma che linguaggio stai usando??
Potresti postare il codice...

Re: Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 19:29
da antex
raffaele63 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4572730#p4572730][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Ciao a tutti,
sto cercando di generare una sequenza numerica, da 1 a x numero, ma casuale e non ripetitiva.
Spiego: non voglio 1-2-3 ecc, e neanche 1-5-2-1-5 ecc. Ho provato con random. randint() e con random.randrange() ma non ottengo la numerazione che voglio.
Non capisco cosa vuoi ottenere: la numerazione deve essere casuale, oppure una numerazione che vuoi tu? Non colgo il senso.

Re: Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 20:10
da raffaele63

Codice: Seleziona tutto

n_sett=input("quanti settori? ")
n_sett=n_sett+1
for n in range(1,n_sett):
    print n
fino a qui è semplice: mi genera da 1 al numero che digito in n_sett (1 2 3 4 ecc.). Quello che vorrei è che detta sequenza sia mischiata ma senza ripetizioni dei numeri componenti la stessa ossia: 2 4 9 3 10 7 ecc. ma solo fino al numero inserito in n_sett.
Ho provato ad immettere dopo istruzione for:

Codice: Seleziona tutto

n_sett=input("quanti settori? ")
n_sett=n_sett+1
for n in range(1,n_sett):
    print random.randint(1,n_sett)
e l'output è:
quanti settori? 10
11,6,6,10,6,10,2,10,2,10, allora perché vi sono 10 numeri e comprende anche 11 che non è richiesto lo so, ma io cerco una lista numerica con tutti i numeri compresi nel range richiesto. Spero di essere stato chiaro.

Re: Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 20:16
da vaeVictis
Non è che sei stato il massimo della chiarezza, ma se vuoi una sequenza "mischiata" di numeri da TOT1 a TOT2, puoi usare random.shuffle

Codice: Seleziona tutto

>>> import random
>>> random.shuffle
<bound method Random.shuffle of <random.Random object at 0x1dfdd00>>
>>> n_sett = 10
>>> foo = range(1, n_sett + 1)
>>> print ','.join([str(i) for i in foo])
1,2,3,4,5,6,7,8,9,10
>>> random.shuffle(foo)
>>> print ','.join([str(i) for i in foo])
8,5,6,4,7,2,3,10,9,1
>>> random.shuffle(foo)
>>> print ','.join([str(i) for i in foo])
10,1,2,4,7,6,9,8,3,5
>>> random.shuffle(foo)
>>> print ','.join([str(i) for i in foo])
9,10,6,8,3,1,5,7,2,4
>>> random.shuffle(foo)
>>> print ','.join([str(i) for i in foo])
10,2,5,9,3,7,4,6,8,1
random.randint non ti garantisce estrazioni di numeri senza ripetizioni, e inoltre comprende (nelle estrazioni) i due estremi che gli passi.

A margine, non modificare il valore della variabile in questo modo:

Codice: Seleziona tutto

n_sett=n_sett+1
Le fai perdere consistenza "logica" con quello che "significa".
Passa direttamente n_sett+1 a range.

Re: Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 21:09
da raffaele63
Ciao, avevo provato ieri sera shuffle, ma da novello sbagliavo il metodo di abbinamento. A dire il vero avevo pensato anche a set (con random.random) ma non mi suonava bene ed ho avuto ragione perché la strada era un'altra. Studiando (le pagine del tutorial e della libreria sono tanteeeee) e con qualche aiutino faccio progressi. Grazie. (ora metto risolto)

Re: [Risolto] Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 21:11
da vaeVictis
Ciao, avevo provato ieri sera shuffle, ma da novello sbagliavo il metodo di abbinamento
il metodo di abbinamento?

p.s.:
da novello
Se qualcosa del codice che ti ho postato non ti è chiara, chiedi pure eh!
Ho usato un paio di cose che potresti ancora non aver visto. Vedi tu.
Ciao.

Re: [Risolto] Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 21:44
da raffaele63
Ho trovato in internet questo mini tutorial: Python tips & tricks. nelle pagine vi sono diversi esempi e da li ho preso una parte di codice relativo a random (vedi sotto):

Codice: Seleziona tutto

n_sett=input("quanti settori? ")
n_sett=n_sett+1
for n in range(1,n_sett):
    sys.stdout.write(str(random.shuffle(1,n_sett)))
La parte di codice (sys eccetera) la uso in altra parte di codice, senza shuffle ma con randint) e li mi andava bene.

p.s.:
da novello
Se qualcosa del codice che ti ho postato non ti è chiara, chiedi pure eh!
Ho usato un paio di cose che potresti ancora non aver visto. Vedi tu.
Ciao.[/quote]

In effetti qualche chiarimento non farebbe male. Ad esempio la variabile "foo" è una variabile a se stante o ha un significato particolare? Invece per join?

Re: [Risolto] Generare una sequenza numerica

Inviato: lunedì 28 aprile 2014, 22:01
da vaeVictis
1) Ti sconsiglio caldamente di imparare a programmare studiando sui vari tutorial online. Usa la via "canonica" (libro :) )
2) Il metodo random.shuffle "mischia" in place una lista. Quella variabile che ho chiamato foo è una lista (in questo caso di interi) che poi viene passata al metodo random.shuffle per essere sottoposta, appunto, ad uno shuffle.
Per in place si intende che ti "opera" sull'oggetto che passi al metodo, modificandolo.
Questa istruzione del tuo codice:

Codice: Seleziona tutto

random.shuffle(1,n_sett)
non funziona, perché non gli stai passando una lista:

Codice: Seleziona tutto

>>> random.shuffle(1,12)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/random.py", line 285, in shuffle
    for i in reversed(xrange(1, len(x))):
TypeError: object of type 'int' has no len()
a differenza che con randint, caso in cui ti funziona:

Codice: Seleziona tutto

>>> random.randint(1,12)
9

Re: [Risolto] Generare una sequenza numerica

Inviato: martedì 29 aprile 2014, 20:47
da vaeVictis
p.s.: Anche se mi aspettavo la domanda, mi è sfuggita quella su join.
È un metodo degli iterabili di Python.
Come ti viene spiegato nell'help:

Codice: Seleziona tutto

>>> help(str.join)
...
Help on built-in function join:

join(...)
    S.join(iterable) -> string
    
    Return a string which is the concatenation of the strings in the
    iterable.  The separator between elements is S.
Gli passi un iterabile e lui ti ritorna una "stringa" in cui gli elementi (dell'iterabile che gli hai passato) sono separati dall'elemento S.

Ad esempio, se la applichi ad una "stringa", che per Python è un iterabile, ottieni:

Codice: Seleziona tutto

>>> foo = "StringaDiProva"
>>> ','.join(foo)
'S,t,r,i,n,g,a,D,i,P,r,o,v,a'
Ora, nel caso dell'esempio che ho fatto nel precedente messaggio, tu hai un altro tipo di iterabile iterabile (la lista foo) che contiene numeri

Codice: Seleziona tutto

>> foo = range(1,10)
>>> foo
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Non puoi applicare direttamente il metodo str.join, perché gli elementi dell'iterabile (foo) che gli passi devono a loro volta essere stringhe:

Codice: Seleziona tutto

>>> ','.join(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, int found
Per questo motivo, ho passato una cosa "diversa" da foo.
Se vedi, l'argomento passato al metodo str.join è:

Codice: Seleziona tutto

<type 'str'>
>>> [ str(i) for i in foo ]
['1', '2', '3', '4', '5', '6', '7', '8', '9']
Questa sintassi si chiama "list comprehension" ed è un modo per generare le liste.
Ho quindi passato a str.join una lista i cui elementi sono quelli di foo, trasformati in stringhe.

Ora... fare questo passaggio tutte le volte è ovviamente uno spreco di risorse. Per fortuna il metodo random.shuffle funziona anche con liste i cui elementi siano "lettere" e non "numeri", quindi puoi fare la "trasformazione" da lista di numeri in lista di lettere solo una volta, all'inizio, e poi passare a join direttamente la lista modificata:

Codice: Seleziona tutto

>>> bar = [ str(i) for i in foo ]
>>> bar
['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> random.shuffle(bar)
>>> print ','.join(bar)
4,3,7,9,2,5,8,1,6
Ovviamente, questo "metodo" non funziona se tu poi devi fare dei conti sugli elementi mischiati.
Era solo per darti qualche spunto di approfondimento :)

Ciao.

Re: [Risolto] Generare una sequenza numerica

Inviato: martedì 29 aprile 2014, 23:59
da raffaele63
Veramente grazie!
Ho apprezzato molto la spiegazione e la semplicità con la quale hai spiegato il percorso da seguire e come.
Studiare da solo (sui libri) alle volte non è sufficiente perché sfugge sempre qualcosa, per questo provo e riprovo cercando anche in rete qualcosa, ma come hai caldamente suggerito, on-line si trova materiale non descritto correttamente.
Ciao!