Comprensión de conjuntos de Python

81

Así que tengo estos dos problemas para una tarea y estoy atascado en el segundo.

  1. Utilice Python Set Comprehension (el equivalente en Python de la notación Set Builder) para generar un conjunto de todos los números primos menores que 100. Recuerde que un número primo es un número entero mayor que 1 y no divisible por ningún número entero distinto de sí mismo y 1. Almacene su conjunto de números primos en una variable (lo necesitará para partes adicionales). Imprima su conjunto de números primos (por ejemplo, con la función de impresión).

  2. Utilice una comprensión de conjunto de Python para generar un conjunto de pares ordenados (tuplas de longitud 2) que consta de todos los pares primos que consisten en primos menores que 100. Un par primo es un par de números impares consecutivos que son primos. Almacene su conjunto de Prime Pairs en una variable. Su conjunto de número 1 será de gran ayuda. Genere su conjunto de pares principales.

Para el primero, esto funciona perfectamente:

r= {x for x in range(2, 101) 
if not any(x % y == 0 for y in range(2, x))} 

Sin embargo, estoy bastante perplejo con el segundo. Creo que debo tomar el producto cartesiano del conjunto r con algo, pero no estoy seguro.

Esto me acerca un poco, pero solo quiero los pares consecutivos.

cart = { (x, y) for x in r for y in r
     if x < y }
usuario3308790
fuente

Respuestas:

69
primes = {x for x in range(2, 101) if all(x%y for y in range(2, min(x, 11)))}

Simplifiqué un poco la prueba, en if all(x%ylugar deif not any(not x%y

También limité el rango de y; no tiene sentido probar para divisores> sqrt (x). Entonces max (x) == 100 implica max (y) == 10. Para x <= 10, y también debe ser <x.

pairs = {(x, x+2) for x in primes if x+2 in primes}

En lugar de generar pares de números primos y probarlos, obtenga uno y vea si existe el primo superior correspondiente.

Hugh Bothwell
fuente
14

Puede obtener soluciones limpias y claras si crea los predicados adecuados como funciones auxiliares. En otras palabras, use la notación del generador de conjuntos de Python de la misma manera que escribiría la respuesta con la notación de conjuntos matemática normal.

Toda la idea detrás de las comprensiones de conjuntos es dejarnos escribir y razonar en código de la misma manera que hacemos las matemáticas a mano.

Con un predicado apropiado en la mano, el problema 1 se simplifica a:

 low_primes = {x for x in range(1, 100) if is_prime(x)}

Y el problema 2 se simplifica a:

 low_prime_pairs = {(x, x+2) for x in range(1,100,2) if is_prime(x) and is_prime(x+2)}

Observe cómo este código es una traducción directa de la especificación del problema, "Un par primo es un par de números impares consecutivos que son primos".

PD: Estoy tratando de darte la técnica correcta de resolución de problemas sin dar la respuesta al problema de la tarea.

Raymond Hettinger
fuente
2
Aunque el problema 2 se puede simplificar a un simple bucle sobre el resultado del problema 1, como se indica en las instrucciones.
tripleee
5

Puedes generar pares como este:

{(x, x + 2) for x in r if x + 2 in r}

Entonces, todo lo que queda por hacer es obtener una condición para que sean primarios, lo que ya hizo en el primer ejemplo.

Una forma diferente de hacerlo: (aunque más lento para grandes conjuntos de números primos)

{(x, y) for x in r for y in r if x + 2 == y}
árboles helados
fuente
3
No estoy seguro de por qué tu mejor manera es mejor. El OP ya tiene los números primos de menos de 100 pulgadas r, así que es {(x, x + 2) for x in r if x + 2 in r}suficiente.
DSM
2
and x % 2 == 1no es necesario.
thefourtheye
2
arreglado, gracias, por alguna razón pensé que los números primos podrían ser pares
icedtrees
2
Por alguna razón, no veo cuáles faltan. Me fijan ([(29, 31), (59, 61), (5, 7), (71, 73), (41, 43), (3, 5), (17, 19), (11, 13)]). ¿Qué pares faltan? Ya aplicó la condición (de ser primo) ar, por lo que el código debería estar bien.
icedtrees
No, tienes toda la razón. Tenía la impresión de que (7,11) y (13,17) etc ... estaban incluidos en los pares primos ya que eran técnicamente "consecutivos" en la lista de primos. Pero ahora lo entiendo.
user3308790