python - barplot - Solo índice necesario: enumerar o(x) rango?
pandas plot (8)
Basado en su código de muestra,
res = [[profiel.attr[i].x for i,p in enumerate(profiel.attr)] for profiel in prof_obj]
Yo lo reemplazaria por
res = [[p.x for p in profiel.attr] for profiel in prof_obj]
Si quiero usar solo el índice dentro de un bucle, debería usar mejor la función range/xrange
en combinación con len()
a = [1,2,3]
for i in xrange(len(a)):
print i
o enumerate
? Incluso si no voy a usar p
en absoluto?
for i,p in enumerate(a):
print i
Escribí esto porque quería probarlo. Así que depende si necesitas los valores con los que trabajar.
Código:
testlist = []
for i in range(10000):
testlist.append(i)
def rangelist():
a = 0
for i in range(len(testlist)):
a += i
a = testlist[i] + 1 # Comment this line for example for testing
def enumlist():
b = 0
for i, x in enumerate(testlist):
b += i
b = x + 1 # Comment this line for example for testing
import timeit
t = timeit.Timer(lambda: rangelist())
print("range(len()):")
print(t.timeit(number=10000))
t = timeit.Timer(lambda: enumlist())
print("enum():")
print(t.timeit(number=10000))
Ahora puede ejecutarlo y obtendrá el resultado más probable, que enum () es más rápido. Cuando comenta la fuente en a = testlist[i] + 1
y b = x + 1
verá que el rango (len ()) es más rápido.
Por el código anterior obtengo:
range(len()):
18.766527627612255
enum():
15.353173553868345
Ahora, al comentar como se indicó anteriormente obtengo:
range(len()):
8.231641875551514
enum():
9.974262515773656
Ese es un requisito poco frecuente: la única información que se utiliza en el contenedor es su longitud. En este caso, de hecho, hacer este hecho explícito y utilizar la primera versión.
Hice una prueba de tiempo y descubrí que el rango es aproximadamente 2 veces más rápido que enumerar. (en Python 3.6 para Win32)
lo mejor de 3, para len (a) = 1M
- enumerar (a): 0.125s
- rango (len (a)): 0.058s
Espero eso ayude.
FYI: Inicialmente comencé esta prueba para comparar la velocidad de python vs vba ... y descubrí que vba es en realidad 7 veces más rápido que el método de rango ... ¿es por mis pobres habilidades con python?
seguramente python puede hacerlo mejor que vba de alguna manera
guión para enumerar
import time
a = [0]
a = a * 1000000
time.perf_counter()
for i,j in enumerate(a):
pass
print(time.perf_counter())
guión para rango
import time
a = [0]
a = a * 1000000
time.perf_counter()
for i in range(len(a)):
pass
print(time.perf_counter())
script para vba (0.008s)
Sub timetest_for()
Dim a(1000000) As Byte
Dim i As Long
tproc = Timer
For i = 1 To UBound(a)
Next i
Debug.Print Timer - tproc
End Sub
Solo usa el range()
. Si va a utilizar todos los índices de todos modos, xrange()
no proporciona ningún beneficio real (a menos que len(a)
sea realmente grande). Y enumerate()
crea una estructura de datos más rica que vas a tirar de inmediato.
Usar xrange con len es un caso de uso bastante común, así que sí, puede usarlo si solo necesita acceder a los valores por índice.
Pero si prefiere usar la enumeración por algún motivo, puede usar el guión bajo (_), es solo una notación que se ve con frecuencia y muestra que no usará la variable de alguna manera significativa:
for i, _ in enumerate(a):
print i
También hay una trampa que puede suceder con el subrayado (_). También es común nombrar a las funciones de ''traducción'' como _ en las bibliotecas y sistemas i18n, así que tenga cuidado de usarlo con gettext o alguna otra biblioteca de este tipo (gracias a @lazyr).
Yo usaría enumerate
porque es más genérico; por ejemplo, funcionará en iterables y secuencias, y la sobrecarga por solo devolver una referencia a un objeto no es tan importante, mientras que xrange(len(something))
aunque (para mí) más fácil de leer según su intención: se romperá en objetos sin soporte para len
...
xrange debería ser un poco más rápido, pero enumerar significará que no necesita cambiarlo cuando se da cuenta de que necesita p
después de todo