2017-01-30 3 views
2

Das ist, was ich ohne eine Schleife erreicht habe, die hässlich ist. Ich bin sicher, dass dies mit einer Schleife durchgeführt werden kann, die sich wiederholende Aussagen ohne:Wie kann ich eine Schleife für diese if-Anweisungen erstellen?

def my_function(my_list_of_words): 
    _digits = re.compile('\d') 
    to_return = [] 

    for i, p in enumerate(my_list_of_words): 
     new_list= [] 
     if 'start' in p: 
      if bool(_digits.search(my_list_of_words[i+1])): 
       new_list.append(p) 
       new_list.append(my_list_of_words[i+1]) 
       if bool(_digits.search(my_list_of_words[i+2])): 
        new_list.append(my_list_of_words[i+2]) 
        if bool(_digits.search(my_list_of_words[i+3])): 
         new_list.append(my_list_of_words[i+3]) 
       to_return.append(" ".join(new_list)) 

    return to_return 

Dies funktioniert gut, aber ich weiß nicht, wie viele Strings mit Zahlen wird es nach "start" sein.

Ich möchte eine Schleife, die weiterhin nach Zahlen in der Liste der Zeichenfolgen sucht, bis der nächste Index keine Nummer hat.

Ich versuchte dies:

def my_function(my_list_of_words): 
    _digits = re.compile('\d') 
    to_return = [] 

    for i, p in enumerate(my_list_of_words): 
     new_list= [] 
     count = 1 
     if 'start' in p: 
      new_list.append(p) 
      while bool(_digits.search(my_list_of_words[i+count])): 
       new_list.append(my_list_of_words[i+count]) 
       ++count 
      to_return.append(" ".join(new_list)) 

    return to_return 

Das aus irgendeinem Grund nicht funktioniert, scheint es für immer Schleife. Ich habe auch versucht:

while True: 
    if bool(_digits.search(my_list_of_words[i+count])): 
    //doo things 
    ++count 
    else: 
    break 

Dies funktioniert nicht für mich auch, es Schleifen für immer.

Darstellung von dem, was ich versuche zu erreichen:

['foo','foo','foo','start', '23', 'a32bc', '43', '332', 'foo', 'start', '23', 'a32bc'] 

produzieren würde

['start 23 a32bc 43 332', 'start 23 a32bc'] 

Lasst uns sagen, dass wir die obige Liste haben, wenn wir 'start' erreichen, ich, ob die nächste überprüfen möchten hat eine Nummer, in unserem Fall 23, wenn ja, dann überprüfen Sie die nächste für die Nummer (enthält 32 so wieder wahr), so weiter, bis die nächste keine Nummer hat.

Wie kann ich dies mit einer Schleife erreichen?

+2

Ich bin ziemlich sicher, '++ count' nichts tut, versuchen' count + = 1 'stattdessen. – MSeifert

+0

Warum zählen Sie Ihre Einträge? Iterieren Sie einfach über sie und brechen Sie, wenn die Bedingung falsch ist. – MKesper

+0

@MSeifert Sie haben recht, bewegen sich von Java zu Python und versuchen immer noch, sich an einige grundlegende Konzepte zu gewöhnen. Dank dafür. Außerdem verwende ich "Pythonanywhere" als Testumgebung, und in seinem Editor wurden weder Fehler noch Syntaxfehler angezeigt, was nicht hilfreich ist. –

Antwort

3

Die Pythonic Version einer Schleife zurück while True: count++ ist ein iterator, kombiniert mit next() function zum nächsten Element vorzurücken. Wenn der Iterator erschöpft ist, wird StopIteration exception ausgelöst.

einen Iterator für Ihre Liste erstellen (mit den iter() function, dann verschachtelten Schleifen verwenden, um den Iterator voraus, wie Sie entsprechen:

def my_function(my_list_of_words, _digits=re.compile('\d').search): 
    word_iter = iter(my_list_of_words) 
    digit_words = None 
    results = [] 
    try: 
     curr = next(word_iter) 
     while True:    
      # scan to the next 'start' value 
      while 'start' not in curr: 
       curr = next(word_iter) 

      # collect digits; curr == start so we advance to the next 
      digit_words = [curr] 
      while True: 
       curr = next(word_iter) 
       if not _digits(curr): 
        break 
       digit_words.append(curr) 
      results.append(' '.join(digit_words)) 
      digit_words = [] 

    except StopIteration: 
     # out of words, append remaining digit_words if there are any. 
     if digit_words: 
      results.append(' '.join(digit_words)) 

    return results 

dieses So springen Elemente bis 'start' gefunden wird, dann Einträge sammelt die Ziffern, schaltet dann auf der Suche nach 'start' zurück, usw., bis StopIteration durch den next() Anruf ausgelöst wird

Demo:.

>>> my_function(['foo','foo','foo','start', '23', 'a32bc', '43', '332', 'foo', 'start', '23', 'a32bc']) 
['start 23 a32bc 43 332', 'start 23 a32bc'] 

Sie könnten alle results.append() Anrufe mit yield ersetzen, um dies zu einem Generator zu machen.

Beachten Sie, dass ich annehme, dass es keine überlappenden Sequenzen geben wird; z.B. 'start' wird nie in einem Wort mit Ziffern in einem zusammenhängenden Ziffernabschnitt angezeigt.

+0

Sehr professionelle Antwort. Iteratoren könnten für Anfänger eine Menge zu begreifen sein, fürchte ich. Danke für die Klärung der Kommentare! :) – MKesper

+0

@MKesper: Angesichts der Tatsache, dass die OP bereits Pseudocode ausgeschrieben hat, die effektiv das gleiche tut (inkrementieren einen Zähler, bis Ihnen die Worte ausgehen), denke ich nicht, dass das ein so großer Sprung ist. –

+0

Dies sollte im offiziellen Python-Tutorial im Kapitel über Sequenzen enthalten sein. – MKesper

1
import re 

def my_function(my_list_of_words): 
    _digits = re.compile('\d') 
    to_return = [] 

    for i, p in enumerate(my_list_of_words): 
     new_list= [] 
     if 'start' in p and i+1 < len(my_list_of_words): 
      if bool(_digits.search(my_list_of_words[i+1])): 
       new_list.append(p) 
       for j in xrange(1,len(my_list_of_words)-i): 
        if bool(_digits.search(my_list_of_words[i+j])): 
         new_list.append(my_list_of_words[i+j]) 
        else: 
         break 
       to_return.append(" ".join(new_list)) 

    return to_return 

print my_function(['foo','foo','foo','start', '23', 'a32bc', '43', '332', 'foo', "donotmatch66", 'start', '23', 'a32bc', 'start']) 

wird

['start 23 a32bc 43 332', 'start 23 a32bc'] 
+0

Gibt es einen Bedarf für die Reichweite? – MKesper

+0

@MKesper: meinst du statt 'xrange'? Nee. – Faibbus

+0

Nein, anstatt nur über die Einträge zu iterieren. – MKesper

0

Hier ein einfaches Programm Primzahlen in Python zu finden, die Ihren for loop in if Zustand abdecken sollen:

def getPrime(X): 
    print("The entered number is ",str(X)) 
    x=int(X) 
    if x==1: 
     print("1 is treated as speacial charater") 
     return False 
    for i in range(2,x): 
     if x%i==0: 
      print("{} is eual to {}x{}".format(x,i,x//i)) 
      return False 
     else: 
      print(x, "is a Prime Number") 
      return True 


print("Please enter number greater than 1 ") 
M =input() 
m=int(M) 
for i in range(2,m): 
    getPrime(i) 
+0

Bitte lassen Sie mich wissen, wenn ich Ihre Frage nicht beantworten kann. – ssr

Verwandte Themen