2017-10-06 12 views
1

J'ai le code suivant que je dois convertir en list-comprehension (un paquebot). Cependant, je suis incapable de le faire. Le code calcule la plage d'entrée des nombres premiers allant de A.convertir le double pour la boucle avec la fonction de lambda et casser à la compréhension de liste

def sieve(A):  
    l = [] 
    f = lambda x : int(x**0.5) 
    for p in range(2,A+1):   
     for i in range(2, f(p) + 1): 
      if p % i == 0: 
       break 
     else: 
      l.append(p) 
    return l 

Jusqu'ici j'ai suivi ce qui ne fonctionne pas. Surtout le break dans for-loop me rejette.

list(set([val for sublist in [[p for i in range(2, f(p) + 1) if p %i != 0 ] for p in range(2,A) ] for val in sublist])) 

EDIT
Ajout de contraintes pour le problème. Le code ne peut être qu'une seule instruction, sans eval ou exec. Le code doit comporter au maximum 160 caractères.

+4

Pourquoi? Je plains la personne qui doit essayer de déchiffrer cette compréhension de la liste. –

+0

Pourquoi, en premier lieu, voulez-vous qu'il soit converti en liste de compréhension? –

+0

Je sais, cela fait partie d'un problème en ligne qui n'accepte qu'une seule solution de ligne. À moins qu'il y ait un autre moyen de fournir un paquebot. –

Répondre

1
[p for p in range(2,A+1) if next((i for i in range(2, int(p**0.5) + 1) if (p % i) == 0),None)==None] 

Le code a une longueur de 100 caractères. Nous utilisons next() pour sortir de l'itération.
Explication

def sieve(A): 
    [p for p in range(2,A+1) if getFirstDiv(p)==None] 

def getFirstDiv(p): 
    next(divIter(p),None) 

def divIter(p): 
    return (i for i in range(2, int(p**0.5) + 1) if (p % i) == 0) 

SORTIE

15 --> [2, 3, 5, 7, 11, 13] 
10 --> [2, 3, 5, 7] 
+0

Ah, donc je manquais sur next(), bon à savoir. Cela fonctionne parfaitement même pour A = 10000 + dans des contraintes de temps données. THX. –

1

Celui-liner fera:

[r for r in [i*all([i if i%j!=0 else 0 for j in range(2,i)]) for i in range(2,x)] if r>0] 

Vous avez juste besoin de mettre x (la valeur maximale).

Note: ce n'est pas particulièrement efficace, même si je suppose que l'efficacité n'est pas le but de cette question.

Explication (code élargi):

filtered = [] 
primes = [] 

for i in range(2,x): 
    # Check that all numbers up to i do not divide i 
    # I realise we only need to check up to int(sqrt(i)) 
    condition = all([i if i%j!=0 else 0 for j in range(2,i)]) 

    # Exploit Python's treatment of bool: number*True = number and number*False=0 
    filtered.append(i*condition) 


for r in filtered: 
    # Take out all the zeros 
    if r>0: 
     primes.append(r)