Extraer elementos de la lista en posiciones impares


100

Entonces quiero crear una lista que sea una sublista de alguna lista existente.

Por ejemplo,

L = [1, 2, 3, 4, 5, 6, 7], Quiero crear una sublista lique licontenga todos los elementos en Lposiciones impares.

Mientras puedo hacerlo

L = [1, 2, 3, 4, 5, 6, 7]
li = []
count = 0
for i in L:
    if count % 2 == 1:
        li.append(i)
    count += 1

Pero quiero saber si hay otra forma de hacer lo mismo de manera eficiente y en menos pasos.


@WaleedKhan: ¿Por qué necesita enumerar comprensiones en una pregunta?
Tamara Wijsman

1
@TomWijsman: enumera las comprensiones . ETA: Ignora eso: busqué y descubrí esta respuesta tuya que indica que estás bromeando. ¡Pon una carita sonriente la próxima vez!
David Robinson

2
@DavidRobinson: Pero si otras personas pueden decir eso, puede que OP no tenga claro lo que quiere decir con dos palabras ambiguas. Simplemente apuñalando aquí y allá con algunos comentarios, para que la gente se prepare y escriba mejor contenido; y para evitar dejar al OP o visitantes despistados ... :)
Tamara Wijsman

Respuestas:


229

Solución

Sí tu puedes:

l = L[1::2]

Y esto es todo. El resultado contendrá los elementos colocados en las siguientes posiciones ( 0basado en, por lo que el primer elemento está en la posición 0, el segundo en, 1etc.):

1, 3, 5

por lo que el resultado (números reales) será:

2, 4, 6

Explicación

El [1::2]al final es solo una notación para dividir la lista. Por lo general, tiene la siguiente forma:

some_list[start:stop:step]

Si lo omitimos start, se 0usaría el valor predeterminado ( ). Por tanto, se seleccionaría el primer elemento (en la posición 0, porque los índices están 0basados ​​en). En este caso, se seleccionará el segundo elemento.

Debido a que se omite el segundo elemento, se utiliza el predeterminado (el final de la lista). Entonces, la lista se itera desde el segundo elemento hasta el final .

También proporcionamos el tercer argumento ( step) que es 2. Lo que significa que se seleccionará un elemento, se omitirá el siguiente, y así sucesivamente ...

Entonces, en resumen, en este caso [1::2]significa:

  1. tome el segundo elemento (que, por cierto, es un elemento extraño, si juzga por el índice),
  2. omitir un elemento (porque tenemos step=2, por lo que estamos omitiendo uno, al contrario de lo step=1que es predeterminado),
  3. toma el siguiente elemento,
  4. Repita los pasos 2 a 3. hasta llegar al final de la lista,

EDITAR : @PreetKukreti dio un enlace para otra explicación sobre la notación de corte de lista de Python. Vea aquí: Explica la notación de corte de Python

Extras: reemplazo del mostrador por enumerate()

En su código, crea y aumenta explícitamente el contador. En Python esto no es necesario, ya que puede enumerar a través de algunos iterables usando enumerate():

for count, i in enumerate(L):
    if count % 2 == 1:
        l.append(i)

Lo anterior tiene exactamente el mismo propósito que el código que estaba usando:

count = 0
for i in L:
    if count % 2 == 1:
        l.append(i)
    count += 1

Más sobre la emulación de forbucles con contador en Python: Accediendo al índice en Python 'for' bucles


@TomWijsman mira esta pregunta para comprender la sintaxis de corte de Python
Preet Kukreti

La pregunta pide posiciones extrañas. Esto da posiciones uniformes (0,2,4,6); parece que OP quiere índices (1,3,5), que serían dados por [1,2,3,4,5,6,7][1::2].
Marcin

@Marcin: Sí, de hecho salí con la misma conclusión (ver corrección). Esto salió después de haber leído detenidamente el código del OP. El problema resultó en una base diferente para la indexación (para mí, el elemento " extraño " significaba el primer elemento, para OP aparentemente era el segundo , así que indexado en 1).
Tadeck

1
@TomWijsman: Lo siento, no me di cuenta de lo que ha cambiado. De hecho, hay un enlace, pero conduce al proyecto Numarray, no al listcorte de Python . Difiere un poco, especialmente porque el listsegmento de 'no guarda referencia a la lista original (en Numarray necesitas llamar explícitamente .copy()para tener algo que no haga referencia a la matriz original). Pero es bueno tener algo que pueda ser mejor para algunos lectores. ¿Le importaría publicar este enlace en el comentario para que pueda votar y aparecerá justo debajo de la respuesta?
Tadeck

@Tadeck "Índices con números impares", naturalmente, significa índices que son números impares.
Marcin

12

Para las posiciones impares , probablemente quieras:

>>>> list_ = list(range(10))
>>>> print list_[1::2]
[1, 3, 5, 7, 9]
>>>>

3

Me gustan las comprensiones de listas debido a su sintaxis Math (Set). Entonces, ¿qué tal esto?

L = [1, 2, 3, 4, 5, 6, 7]
odd_numbers = [y for x,y in enumerate(L) if x%2 != 0]
even_numbers = [y for x,y in enumerate(L) if x%2 == 0]

Básicamente, si enumera sobre una lista, obtendrá el índice xy el valor y. Lo que estoy haciendo aquí es poner el valor yen la lista de salida (par o impar) y usar el índice xpara averiguar si ese punto es impar ( x%2 != 0).


1
¿No debería enumerarse (L) en lugar de enumerar (elementos)?
ab123

0

Puede hacer uso del operador AND bit a bit &. Veamos a continuación:

x = [1, 2, 3, 4, 5, 6, 7]
y = [i for i in x if i&1]
>>> 
[1, 3, 5, 7]

El operador AND bit a bit se usa con 1, y la razón por la que funciona es que, cuando se escribe en binario, un número impar debe tener su primer dígito como 1. Comprobemos

23 = 1 * (2**4) + 0 * (2**3) + 1 * (2**2) + 1 * (2**1) + 1 * (2**0) = 10111
14 = 1 * (2**3) + 1 * (2**2) + 1 * (2**1) + 0 * (2**0) = 1110

Y la operación con 1 solo devolverá 1 (1 en binario también tendrá el último dígito 1), si el valor es impar.

Consulte la página del operador Bitwise de Python para obtener más información.

PD: puede usar tácticamente este método si desea seleccionar columnas pares e impares en un marco de datos. Digamos que las coordenadas xey de los puntos clave faciales se dan como columnas x1, y1, x2, etc. Para normalizar las coordenadas xey con los valores de ancho y alto de cada imagen, simplemente puede realizar

for i in range(df.shape[1]):
    if i&1:
        df.iloc[:, i] /= heights
    else:
        df.iloc[:, i] /= widths

Esto no está exactamente relacionado con la pregunta, pero para los científicos de datos y los ingenieros de visión por computadora este método podría ser útil.

¡Salud!


-1

lista_ = lista (rango (9)) imprimir (lista_ [1 :: 2])


por favor responda con una breve explicación y coloque algunos bloques de código correctamente formateados. Gracias
venkata krishnan
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.