2017-09-28 5 views
1

Je tente d'écrire le code suivant en tant que doublure.Compréhension de liste imbriquée avec contrôle de flux

for x in range(a, b+1): 
    prime = True 
    for y in range(2, int(x**0.5)): 
    if x%y == 0: 
     prime = False 
     break 
    if prime: 
    return x 

Ceci recherche les nombres premiers entre a et b. Je vais enregistrer chaque nombre premier dans une liste. Le code ci-dessus vérifie chaque nombre dans la gamme pour la primalité. Le problème est que je dois écrire cette boucle imbriquée comme une compréhension de liste d'une ligne. Le problème que j'ai est que la compréhension de la liste ne passera pas par la deuxième boucle. Il va vérifier avec 2, puis sortir de la boucle.

J'ai essayé cette approche, et il a lamentablement échoué: ([x for x in range(10, 21) for y in range(2, int(x**0.5)) if x%y != 0])

+0

Ils code que vous avez montré n'a pas beaucoup de sens. 'next' est une fonction intégrée que vous pouvez appeler sur un itérateur, ce n'est pas une déclaration car vous semblez l'utiliser ici. Voulez-vous dire «continuer»? C'est une déclaration, même si elle ne va pas continuer la boucle externe dont je pense que votre algorithme a besoin pour fonctionner correctement. Vous pouvez le faire fonctionner en utilisant 'break' dans le' if' et en mettant la ligne 'return' dans un bloc' else' attaché à la boucle interne 'for' (un peu étrange de syntaxe Python). – Blckknght

+0

Pourquoi pensez-vous qu'il "saute" hors de la boucle? La ligne de code que vous présentez ne produira aucune sortie visible. La partie de votre code entre crochets est une compréhension de liste, que vous associeriez généralement à un nom de variable. Ensuite, vous pouvez l'imprimer, par exemple, et alors seulement vous verrez s'il y a quelque chose dedans. –

+0

Pourquoi l'écrivez-vous en tant que liste de compréhension? Vous ne voulez pas de liste vous voulez une seule valeur. – chepner

Répondre

0
Prime_numbers_list = [x for x in range(a, b+1) 
         if all(x%y !=0 for y in range(2, int(x**0.5)))] 
+0

x/2 n'est pas la même chose que x ** 0.5. –

+0

Cela fonctionne parfaitement! Je ne savais pas à propos de la fonction tout. C'est très utile. – ddcastrodd

+0

@ddcastrodd, je ne crois pas qu'une liste * parfaite * de nombres premiers inclut 1, 4, 6, 8, 9, 15, 25, 35, etc.que ce code produit actuellement quand je l'exécute. Le bug est 'int (x ** 0.5)' devrait être 'int (x ** 0.5) + 1' car c'est le point final d'une plage. – cdlane

2

Je construirais une liste interne des résultats modulaires, et vérifier s'il y a des zéros:

[x for x in range(10, 21) if 0 not in (x%y for y in range(2, int(x**0.5)))] 
1

Si je comprendre votre intention correctement, vous essayez de trouver le plus petit prime entre a et b dans une seule ligne. Vous avez du code actuel, mais ce que vous avez montré n'a aucun sens. Je pense que la logique que vous tentiez de montrer pourrait fonctionner comme ceci:

def find_prime_between(a, b): 
    for x in range(a, b+1): 
     for y in range(2, int(x**0.5)): 
      if x%y == 0: 
       break 
     else: 
      return x 

Une façon de transformer cela en une seule ligne est d'utiliser la fonction all builtin. Il peut remplacer la boucle interne, y compris le comportement de court-circuité provenant des blocs break et else. Pour la boucle extérieure, je suggère d'utiliser l'appel next sur un générateur, qui obtient la première valeur cédée par le générateur:

result = next(x for x in range(a, b+1) if all(x % y != 0 for y in range(2, int(x**0.5)))) 

Par défaut next soulèvera StopIteration si le générateur ne donne rien (parce qu'il ne sont pas des nombres premiers entre a et b). Si vous voulez qu'il renvoie une autre valeur (telle que None) dans cette situation, vous pouvez le passer en second argument à next. Cela exigera l'expression du générateur à envelopper entre parenthèses, car ce n'est pas le seul argument:

result = next((x for x in range(a, b+1) if all(x%y!=0 for y in range(2, int(x**0.5)))), None) 

Cela prend un peu de compression pour tenir sur une seule ligne dans cette réponse sans une barre de défilement.