crear un elemento de duplicación de dubs en una lista de comprensión en python

0

Quiero crear un elemento de duplicación en una lista de comprensión en Python

En Python puede tener varios iteradores en una lista de comprensión, como

[(x,y) for x in a for y in b]

para algunas secuencias adecuadas ay b. Soy consciente de la semántica de bucle de las listas por comprensión de Python.

Mi pregunta es: ¿Puede un iterador en la comprensión referirse al otro? En otras palabras: ¿Podría tener algo como esto?

arr = [1,2,3,4]
dubs = []
dubs = [[x] + [arr[arr.index(x)]] for x in ]
dubs = [x for l in dubs for x in l]

Como ejemplo, si tengo una lista simple:

arr = [1,2,3,4]

cuál sería la expresión de comprensión de la lista para lograr este resultado:

dubs = [1, 1, 2, 2, 3, 3, 4, 4]

Enumere únicamente las respuestas de comprensión.

4
  • 2
    [i for i in arr for _ in range(2)] ?
    jpp
    28/04/18 a las 18:48
  • 2
    Su redacción es muy confusa aquí. [1,2,3,4]no es una lista anidada, es solo una lista plana de ints. 28/04/18 a las 18:55
  • Un buen (o no) truco list((yield i) or i for i in arr) 28/04/18 a las 18:55
  • ¿Cuál es el punto de [x] + [arr[arr.index(x)]] ??? solo hazlo [x, x]. 28/04/18 a las 18:59
2

Si desea cambiar su código existente para que funcione, primero cree una lista anidada y luego aplanándola:

dubs = [[x]+[x] for x in arr]
dubs = [x for l in dubs for x in l]

En otras palabras, lo que necesita para recorrer (lo que parecía estar atascado) es solo el elemento de arr, y lo que necesita agregar a cada elemento singleton [x]es solo otra copia de [x]. Con tu [arr[arr.index(x)]], estás tratando de buscar xen la matriz solo para poder recuperar el valor de lo que encuentres, que será xsi funciona, así que usa x.


Puedes hacer esto un poco mejor:

dubs = [[x]*2 for x in arr]
dubs = [x for l in dubs for x in l]

O, por supuesto:

dubs = [[x,x] for x in arr]
dubs = [x for l in dubs for x in l]

Pero probablemente sea más simple, aunque menos conciso, hacer esto:

dubs = [[x for _ in range(2)] for x in arr]
dubs = [x for l in dubs for x in l]

Y luego, como jpp señaló en un comentario, puede simplificar eso para:

dubs = [x for x in arr for _ in range(2)]

O, alternativamente, observe que todo lo anterior nos está dando las mismas cosas que [list(z) for z in zip(arr, arr)]. Y si solo estamos acoplando el zip, no necesitamos convertirlo en una lista de listas en lugar de un iterador de tuplas, solo utilícelo como está:

dubs = zip(arr, arr)
dubs = [x for l in dubs for x in l]

... que puedes volver a simplificar:

[x for l in zip(arr, arr) for x in l]
2
  • [[x] * 2 para x en arr] dará una lista anidada ,,
    Roushan
    28/04/18 a las 19:02
  • @Roushan Sí, si desea que funcione creando una lista anidada y aplanándola, obviamente necesita crear una lista anidada. 28/04/18 a las 19:02
0

Me parece que desea el índice y el elemento en lugar del elemento dos veces. En ese caso, querrá utilizar enumerate(). El segundo parámetro de enumerate()especifica el índice inicial que se utilizará al devolver las tuplas (índice, valor). Para empezar, 0omita el startparámetro.

dubs = [(i, v) for i, v in enumerate(arr,1)] 

Esto dará una lista de tuplas que se pueden aplanar como mostró @abarnert

dubs = [x for l in dubs for x in l]
2
  • ¿Por qué cree que quiere los índices? La redacción de la pregunta no es tan clara, pero su intento de solución no usa el índice, usa arr[the index], lo que supongo que debe haber tenido alguna razón para hacerlo. (Además, el nombre dubssugiere que quiere dobles). 28/04/18 a las 19:13
  • @abarnert Estoy de acuerdo en que la redacción no es clara. Hay espacio para la interpretación de la salida deseada. Tu respuesta cubre [x]*2muy bien la opción. Pensé que pondría esta opción en caso de que OP (o alguien que busque en el futuro) quiera los índices. 28/04/18 a las 19:24
-2

bucle el mismo elemento dos veces, entonces resultará duplicado

In [6]: [i for i in arr for h in range(2)]
Out[6]: [1, 1, 2, 2, 3, 3, 4, 4]

Uno simple sin comprensión de la lista si tiene una lista ordenada

In [7]: sorted(arr*2)
Out[7]: [1, 1, 2, 2, 3, 3, 4, 4]
2
  • 1
    el sortedque asume que desea el resultado en orden ordenado, lo cual no está claro y supongo que no es el caso 28/04/18 a las 18:56
  • 1
    sortedno hará lo correcto a menos que pueda asumir que la entrada siempre será exactamente la misma que en el ejemplo (en cuyo caso podría simplemente codificar [1,1,2,2,3,3,4,4]y terminar, por lo que no tiene sentido hacer nada más complicado). 28/04/18 a las 18:56