2016-06-13 12 views
0

Ich benutze jetzt Python, um aufeinanderfolgende großgeschriebene Wörter (mindestens zwei) in einem Text zu extrahieren.Funktionale Programmierung mit Python zum Extrahieren aufeinanderfolgender großgeschriebener Wörter

Zum Beispiel gibt es einen Satz

Hollywood ist ein Viertel in der zentralen Region von Los Angeles.

Dann wird die erwartete Ausgabe sollte

Los Angeles sein

Ich versuche, diese Sache in einer funktionalen Programmierung Art und Weise zu tun.

import itertools 
import string 
import operator 

text = "Take any tram, U-bahn or bus which stops at Düsseldorf Hauptbahnhof (HBF). Leave the station via the main exit Konrad Adenauer Platz, you will see trams and buses in front of the station. Walk up Friedrich Ebert Straße turning right into the third street which is the Oststraße." 

def fold(it): 
    def fold_impl(x, y): 
     return itertools.starmap(operator.and_, zip(x, itertools.islice(y, 1, None))) 
    return fold_impl(*itertools.tee(it)) 

def unfold(it): 
    def unfold_impl(x, y): 
     return itertools.starmap(operator.or_, zip(itertools.chain(x, [False]), itertools.chain([False], y))) 
    return unfold_impl(*itertools.tee(it)) 

def ngrams(it, n): 
    return it if n <= 1 else unfold(ngrams(fold(it), n - 1)) 

def ngrams_idx(it, n): 
    return (sorted(x[0] for x in g) for k, g in itertools.groupby(enumerate(ngrams(it, n)), key=lambda x: x[1]) if k) 

def booleanize(text_vec): 
    return map(lambda x: x[0] in string.ascii_uppercase, text_vec) 

def ngrams_phrase(text_vec, n): 
    def word(text_vec, idx): 
     return ' '.join(map(lambda i: text_vec[i], idx)) 
    return [word(text_vec, idx) for idx in ngrams_idx(booleanize(text_vec), n)] 

Aber ich denke, ich es ein bisschen zu kompliziert mache, gibt es eine einfachere Möglichkeit, sich mit dieser Frage zu beschäftigen mit funktionalen Programmierung?

+1

Wie verwenden Sie diese Funktionen? Sie rufen keines von ihnen mit 'Text' an. –

+0

@LutzHorn rufen Sie die letzte Funktion ngrams_phrase, und der Parameter sollte der Text nach der Aufspaltung und die Mindestanzahl von aufeinanderfolgenden Großbuchstaben Wörter, BTW, thx für die Bearbeitung :) – hui

Antwort

1

Werfen Sie einen Blick auf diese:

from itertools import takewhile 

text = "Take any tram, U-bahn or bus which stops at Düsseldorf Hauptbahnhof (HBF). Leave the station via the main exit Konrad Adenauer Platz, you will see trams and buses in front of the station. Walk up Friedrich Ebert Straße turning right into the third street which is the Oststraße." 

def take_upper(text): 
    it = iter(text.split()) 
    return [[i]+list(takewhile(lambda x: x[0].isupper(), it)) for i in it if i[0].isupper()] 

def remove_singles(text_uppers): 
    return [l for l in text_uppers if len(l) > 1] 

remove_singles(take_upper(text)) 
+0

Thx, aber ich habe noch eine Frage: gibt es einen Weg zu Listenkonkaten vermeiden? – hui

+0

Sie könnten eine andere einfache Funktion schreiben, die '[i]' und die von 'takewhile' erzeugte Liste aufnimmt, sie zusammenfasst (durch Aufruf von' list.extend') und eine neue Liste zurückgibt. –

1

ist nicht wirklich eine gute Praxis in Python, aber der kürzeste Weg ist, den splited Text zu reduzieren:

p = "Hollywood is a neighborhood in the central region of Los Angeles.".split() 
t, _ = reduce(lambda (l, v), x: (l+[v, x], x) if v[0].isupper() and x[0].isupper() else (l, x), p, ([], "a")) 
['Los', 'Angeles.'] 
1

denke ich, der Anruf Eintrag würde sei ngram_phrase(text.split(), 2) und OP ist auf der Suche nach das ganze Auftreten von Phrasen, deren Anzahl von konsekutiven großgeschriebenen Initialen mindestens 2 ist, z Wenn Sie das Code-Snippet zusammen mit text ausführen, wird ["Düsseldorf Hauptbahnhof", "Konrad Adenauer Platz", "Friedrich Ebert Straße"] angezeigt.

1

Ich hätte eine der obigen Antworten zur Verfügung gestellt, aber sie wurden bereits zur Verfügung gestellt! Also habe ich die folgende Funktion geschrieben, damit Sie den Fluss sehen können.

def find_proper(text): 
    text = text.rstrip().split(' ') 
    proper = [] 
    data, cnt, pos, str = [x[0].isupper() for x in text], 0, 0, '' 
    while True: 
     if pos == len(text): 
      if cnt > 1: 
       proper.append(str.rstrip()) 
      break 
     if data[pos]: 
      cnt += 1 
      str += text[pos]+' ' 
     else: 
      if cnt > 1: 
       proper.append(str.rstrip()) 
      str = '' 
      cnt = 0 
     pos += 1 
    return proper 
print find_proper(text) 
Verwandte Themen