2017-02-20 2 views
3

experimentiere ich zur Zeit mit dem Einsatz von map, filter und reduce in Python 3.6 um. Was ich versuche zu tun, da eine Liste der Wörterbücher, ändern Sie alle mit einem bestimmten Schlüssel zugeordnet Werte zu einem Kleinwert. Zum Beispiel:Wie verwendet man die Zuordnung, um Zeichenfolgen in einem Wörterbuch klein zu schreiben?

message_one = {"content": "I'm glad I know sign language, it's pretty handy."} 
message_two = {"content": "I am on a seafood diet. Every time I see food, I eat it."} 
message_three = {"content": "Labyrinths are amazing."} 
messages = [message_one , message_two , message_three] 

print(to_lowercase(tweets)) 
#to_lowercase should just return the a list of dictionaries, but content lower-cased. 

versuchte ich Karte auf den ersten Einsatz.

def to_lowercase(messages): 
    lower_case = map(lambda x: x["content"].lower(), messages) 
    return lower_case 

Dies scheint jedoch nur eine Liste aller Inhalts-Nachrichten in einer Liste zurückzukehren und nicht das Wörterbuch Format perserve. Ich glaube nicht, reduce in diesem Szenario richtig sein würde, weil ich nicht bin auf der Suche um einen einzelnen Wert am Ende zurückzukehren, und filter scheint nicht sinnvoll, entweder hier.

Wie würde ich entweder verwenden map, reduce oder filter diesen Job zu erreichen?

+0

Nein, 'reduce()' und 'filter()' sind nicht die richtigen Werkzeuge hier. Sie würden sehr unterschiedliche Dinge tun. 'filter()' wird verwendet, um * Elemente aus einer Liste auszuwählen, und 'reduce()' wird verwendet, um eine Akkumulation zu erzeugen. Wie eine Summe oder eine Liste oder irgendetwas anderes, das erfordert, dass ein Zwischenergebnis mit dem nächsten Element aus der Sequenz aktualisiert wird. Dies sind nicht die Werkzeuge, nach denen Sie suchen. –

+0

Gibt es weitere Schlüssel in den Wörterbüchern, die beibehalten werden müssen? Aktualisieren Sie die Wörterbücher * an Ort und Stelle * akzeptabel oder müssen Sie Kopien erstellen? –

+0

Möchten Sie die Werte im vorhandenen Wörterbuch * ändern * oder möchten Sie ein * neues * Wörterbuch mit den Kleinbuchstaben zurückgeben? – BrenBarn

Antwort

2

(Beachten Sie, diese Antwort vorausgesetzt, dass Sie Python 2 verwenden, wenn Sie Python 3 nehmen in Konto verwenden, dass map() gibt einen Iterator und müssen Sie eine Schleife von einer Art hinzufügen, um die Ergebnisse zu sehen).

Wenn Sie sich mit map() bestehen, dann möchten Sie eine neue Funktion erstellen, um jede bestehende Wörterbuch anzuwenden:

def dict_lowercase_content(d): 
    """Produces a copy of `d` with the `content` key lowercased""" 
    copy = dict(d) 
    if 'content' in copy: 
     copy['content'] = copy['content'].lower() 
    return copy 

def to_lowercase(tweets): 
    return map(dict_lowercase_content, tweets) 

Die dict_lowercase_content() keine Annahmen über dem macht, was Tasten sind in dem Wörterbuch; es wird eine flache Kopie von alle die Schlüssel erstellen und wenn ein content Schlüssel vorhanden ist, es klein geschrieben wird.

Natürlich, wenn Sie sicher sein können, dass nur der Schlüssel content wichtig und immer vorhanden ist, könnten Sie nur völlig neue Wörterbücher mit nur diesem Schlüssel erstellen;

def to_lowercase(tweets): 
    return map(lambda d: {'content': d['content'].lower()}, tweets) 

Wenn Wörterbücher in-place ist in Ordnung, aber (was effizienter wäre), nur eine Schleife verwenden Aktualisierung:

def to_lowercase(tweets): 
    for tweet in tweets: 
     if 'content' in tweet: 
      tweet['content'] = tweet['content'].lower() 

Beachten Sie, dass diese Funktion gibt None! Dies ist die Python-Konvention; Wenn Sie änderbare Objekte an Ort und Stelle ändern, geben Sie diese Objekte nicht erneut zurück, da der Aufrufer bereits eine Referenz besitzt.

können Sie nicht reduce() oder filter() für diesen Job verwenden.

  • filter()wählt Elemente aus dem iterable. Du wählst nicht, du verwandelst dich.

  • reduce()Aggregatelemente; Jedes Element aus der Eingabe wird zusammen mit einem laufenden Ergebnis an eine Funktion übergeben. Was auch immer die Funktion zurückgibt, wird als das aktualisierte Ergebnis genommen.Denken Sie darüber nach, ob Sie einen Baum summieren, verketten oder durchqueren. Wieder aggregieren Sie nicht, Sie transformieren.

+0

Ich weiß, dass Sie wissen :) aber ... wenn Sie das Ergebnis von 'to_lowercase()' als OP drucken, erhalten Sie '' es sei denn, Sie verwenden Python 2 oder konvertieren zu 'list'. Deshalb verwende ich nicht viel Karte am Ende einer Kette (ok die Frage zu sehen, OP ist eindeutig mit Python 2) –

+0

@ Jean-FrançoisFabre: die Tatsache, dass sie auch zu reduzieren betrachten, ist ein totes Werbegeschenk. –

+0

Ja, das habe ich auch gesehen. Glücklicherweise ist "reduce" in "functools" nun "versteckt" (buried?) Und niemand hat jemals die Idee, es zu benutzen: Sie erhalten keine extra Punkte für die Verwendung von 'reduce'! –

2

Mit map:

map(lambda x: {'content': x['content'].lower()}, messages) 

Ohne map:

[{'content': x['content'].lower()} for x in messages] 

Ohne map, aber robuster:

[{y: x[y].lower()} for x in messages for y in x] 
3

Einfache Sol ution eine Liste der neuen dicts mit klein geschrieben Werte erhalten:

dicts = [{k:v.lower() for k,v in d.items()} for d in messages] 
print(dicts) 

Der Ausgang:

[{'content': "i'm glad i know sign language, it's pretty handy."}, {'content': 'i am on a seafood diet. every time i see food, i eat it.'}, {'content': 'labyrinths are amazing.'}] 
2

map() ist eine integrierte in Funktion höherer Ordnung, die eine Sammlung zu verwandeln. Wir liefern eine anonyme Funktion (Lambda) für die auszuführende Map, anstatt die Collection selbst als Argument bereitzustellen. Eine Möglichkeit zu erreichen, was Sie wollen, wäre:

transformed_messages = list(map(lambda x: {'content':x['content'].lower()}, messages)) 
Verwandte Themen