2010-12-21 6 views
175
>>> range(1,11) 

que¿Por qué el rango (inicio, final) no incluye el final?

[1,2,3,4,5,6,7,8,9,10] 

1-11 ¿Por qué no da?

¿Acaban de decidir hacerlo de forma aleatoria o tiene algún valor que no estoy viendo?

+18

'rango (len (s))' –

+7

leer Dijkstra, ewd831 – SilentGhost

+3

Básicamente, usted está eligiendo un conjunto de errores de uno por uno para otro. Es más probable que un conjunto haga que sus bucles finalicen antes, el otro es probable que cause una excepción (o un desbordamiento del búfer en otros idiomas). Una vez que haya escrito un montón de código, verá que la elección del comportamiento 'range()' tiene sentido con mucha más frecuencia –

Respuesta

150

Porque es más común llamar a range(0, 10) que devuelve [0,1,2,3,4,5,6,7,8,9] que contiene 10 elementos que equivalen a len(range(0, 10)). Recuerde que los programadores prefieren la indexación basada en 0.

Además, considere el siguiente fragmento de código común:

for i in range(len(li)): 
    pass 

Podría ver que si range() subió a exactamente len(li) que esto podría ser problemático? El programador debería restar explícitamente 1. Esto también sigue la tendencia común de los programadores que prefieren for(int i = 0; i < 10; i++) sobre for(int i = 0; i <= 9; i++).

Si llama rango de un salto de frecuencia 1, es posible que desea definir su propia función:

>>> range1 = lambda start, end: range(start, end+1) 
>>> range1(1, 10) 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
+27

Si ese fuera el razonamiento, ¿no serían los parámetros 'range (inicio, conteo)'? –

+0

ah, entonces realmente es porque x puede ser 0 – BigOmega

+2

@shogun El valor inicial por defecto es 0, es decir 'range (10)' es equivalente a 'range (0, 10)'. – marcog

6

La longitud de la gama es el valor máximo menos el valor inferior.

Es muy similar a algo como:

for (var i = 1; i < 11; i++) { 
    //i goes from 1 to 10 in here 
} 

en un lenguaje de estilo C.

También como rango de Ruby:

1...11 #this is a range from 1 to 10 

Sin embargo, Ruby reconoce que muchas veces querrá incluir el valor terminal y ofrece la sintaxis alternativa:

1..10 #this is also a range from 1 to 10 
+10

Gah! No uso Ruby, pero me puedo imaginar que '1..10' vs' 1 ... 10' es difícil de distinguir entre cuando se lee el código. – marcog

+2

@marcog - cuando sabes que existen las dos formas, tus ojos sintonizan con la diferencia :) – Skilldrick

+8

El operador de rango de Ruby es perfectamente intuitivo. La forma más larga te da la secuencia más corta. * tos * –

17

rangos exclusivos tienen algunas beneficios:

Por un lado, cada elemento en range(0,n) es un índice válido para las listas de longitud n.

También range(0,n) tiene una longitud de n, no n+1 que incluiría un rango incluido.

15

Funciona bien en combinación con la indexación basada en cero y len(). Por ejemplo, si tiene 10 elementos en una lista x, están numerados 0-9. range(len(x)) le da 0-9.

Por supuesto, la gente le dirá que es más Ptónico hacer for item in x o for index, item in enumerate(x) en lugar de for i in range(len(x)).

El corte funciona de esta manera: foo[1:4] son los elementos 1 a 3 de foo (teniendo en cuenta que el elemento 1 es en realidad el segundo elemento debido a la indexación basada en cero). Por consistencia, ambos deberían funcionar de la misma manera.

Lo considero como: "el primer número que desea, seguido del primer número que no desea quiere". Si quiere 1-10, el primer número que no quiere es 11, entonces es range(1, 11).

Si se vuelve engorroso en una aplicación particular, es bastante fácil de escribir una pequeña función auxiliar que se suma 1 al índice final y llama range().

+2

+1 para mantener la coherencia con el corte. –

+1

De acuerdo en rebanar. 'w = 'abc'; w [:] == w [0: len (w)]; w [: - 1] == w [0: len (w) -1]; ' – kevpie

+0

' def full_range (inicio, parada): rango de retorno (inicio, parada + 1) ## función auxiliar ' – nobar

4

considerar el Código

for i in range(10): 
    print "You'll see this 10 times", i 

La idea es que se obtiene una lista de longitud y-x, que se puede (como se ve arriba) iterar.

Lectura en the python docs para el rango: consideran la iteración for-loop el uso principal.

8

También es útil para rangos de división; range(a,b) se puede dividir en range(a, x) y range(x, b), mientras que con rango incluido escribiría x-1 o x+1. Aunque rara vez necesita dividir rangos, tiende a dividir listas con bastante frecuencia, que es una de las razones por las que cortar una lista l[a:b] incluye el elemento a-ésimo pero no el b-ésimo. Entonces range que tiene la misma propiedad lo hace muy consistente.

9

Aunque hay algunas explicaciones algorítmicos útiles aquí, creo que puede ayudar a añadir un poco de razonamiento simple 'vida real' de por qué funciona de esta manera, que he encontrado útiles para presentar el tema a los jóvenes recién llegados:

Con algo como 'rango (1,10)' puede surgir confusión al pensar que el par de parámetros representa el "inicio y fin".

En realidad es iniciar y "detener".

Ahora, si eran el valor "final", entonces, sí, se podría esperar que el número podría ser incluido como la entrada final de la secuencia. Pero no es el "final".

Otros llaman equivocadamente a ese parámetro "count" porque si solo usas 'range (n)' entonces sí, por supuesto, itera 'n' veces. Esta lógica se rompe cuando agrega el parámetro de inicio.

El punto clave es recordar su nombre: "stop". Eso significa que es el punto en el que, cuando se alcanza, la iteración se detendrá inmediatamente. No después de ese punto.

Por lo tanto, aunque "start" representa el primer valor que se incluirá, al alcanzar el valor "stop" se "rompe" en lugar de continuar procesando "that one well" antes de detenerse.

Una analogía que he usado para explicar esto a los niños es que, irónicamente, ¡se comporta mejor que los niños! No se detiene después de se supone que - se detiene inmediatamente sin terminar lo que estaba haciendo.(Consiguen esto;))

Otra analogía - cuando se conduce un coche no lo hace pase una parada/rendimiento/'ceder' signo y terminar con él sentado en algún lugar próximo a, o detrás , tu carro. Técnicamente aún no lo has alcanzado cuando te paras. No está incluido en las "cosas que pasó en su viaje".

¡Espero que algo de eso ayude a explicar a Pythonitos/Pythonitas!

Cuestiones relacionadas