Zunächst filter und map:
>>> liste1 = [ 1, 2, 3, 4, 5 ] >>> import math >>> map(math.sqrt, liste1) # apply math.sqrt to each element [1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979] >>> map(lambda x: x**0.5, liste1) # same with lambda function [1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979] >>> filter(lambda x: x % 2 == 0, liste1) [2, 4] >>> map(lambda x: x*10, filter(lambda x: x % 2 == 0, liste1)) [20, 40]
>>> [element**0.5 for element in liste1] [1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979] >>> [element for element in liste1 if element % 2 == 0] [2, 4] >>> [element*10 for element in liste1 if element % 2 == 0] [20, 40]
List comprehensions haben folgenden allgemeine Form:
[ expr(element) for element in iterable if pred(element) ]mit
Man kann auch mehrere Listen kombinieren:
[(x,y) for x in range(5) for y in range(5) ] [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (3, 0), (3, 1), (3, 2), (3, 3), (3, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4)]und jeweils auch noch if Bedingung einbauen:
[(x,y) for x in range(5) if x % 2 == 0 for y in range(5) if y % 2 == 1] [(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]damit erhält man eine Kombination aller geraden Zahlen von 0 bis 4 und aller ungeraden Zahlen von 0 bis 4.
Es entspricht einer doppelten for Schleife:
result = [] for x in range(5): if x % 2 == 0: for y in range(5): if y % 2 == 1: result.append((x,y))Mit expliziten for Schleifen übersichtlicher und leichter verständlich, aber deutlich aufwendiger beim Schreiben und wesentlich langsamer bei der Ausführung.
Analog zu list comprehensions gibt es die dict comprehensions
sqdict = { i : i**2 for i in range(10) } print ( sqdict ) {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
a=[ 1,2,3] b=['a','b','c'] zip(a,b) [(1, 'a'), (2, 'b'), (3, 'c')]Ergibt kombinierte Liste von tuples
Praktische Anwendung – Skalarprodukt:
a = [ 0.3, 1.8, -2.2 ] b = [ -2.5, 3.8, 0.4] sp = sum([ x*y for x,y in zip(a,b)])
Kann leicht erweitert werden um 2 Listen in ein dict zu kombinieren:
d = { x[1] : x[0] for x in zip(a,b) } print(d) {'a': 1, 'c': 3, 'b': 2} # Oder direkter ... d = dict(zip(b,a))
Im collections module gibt es nützliche Hilfs-Klassen zur Arbeit mit Listen und Dicts. Hier Beispiel zum Bestimmen der Häufigkeit von Wörtern in Text-Datei:
# # python3 version import urllib.request # open Kant's Text f=urllib.request.urlopen("https://goo.gl/rGqW4k") # split into words words=[] for line in f: # iteriere ueber alle Zeilen line=line.decode("utf-8") # Decoding the binary data to text. words += line.split() # packe Words in list print ("Zahl der Woerter:",len(words)) # or more direct w/ double list-comprehension: # words=[ word for line in f for word in line.split() ] # # count words v1 word_counts = {} for word in words: if word in word_counts: word_counts[word] += 1 else: word_counts[word] = 1 print ("V1:", word_counts["Vernunft"]) # Umstaendlich ... # # count words v2 word_counts = {} for word in words: try: word_counts[word] += 1 except: word_counts[word] = 1 print ("V2:", word_counts["Vernunft"]) # Auch umstaendlich ... # # count words v3 from collections import defaultdict word_counts = defaultdict(int) for word in words: word_counts[word] += 1 print ("V3:", word_counts["Vernunft"]) # defaultdict(int) initialisiert Eintraege beim Ansprechen automatisch auf int() = 0 # # oder noch einfacher ... from collections import Counter word_counts=Counter(words) # # Counter liefert eine Art dict zurueck mit das als Wert die Haeufigkeit enthaelt: print ("V4:", word_counts["Vernunft"]) # und weitere Methoden ... print (word_counts.most_common(10)) # die 10 haeufigsten ...
Ein weiteres gängiges Problem ist, dass man beim Iterieren über eine Liste sowohl das jeweilige Element als auch den Index haben will.
# # find largest element in list, # both index and value of this element # nums = [ 1,5,8,3,7,6,15,11 ] # test list with some numbers maxv=nums[0] imax = 0 # classical method-1 for i in range(len(nums)): # index loop if nums[i]>maxv: maxv = nums[i] imax = i print ("1:", maxv, imax ) # # classical method-2 maxv=nums[0] imax = 0 i = 0 for x in nums: # keep separate counter/index if x>maxv: maxv = x imax = i i += 1 print ("2:", maxv, imax )
# # python way: better use enumerate # maxv=nums[0] imax = 0 for i,x in enumerate(nums): # provides index,value if x>maxv: maxv = x imax = i ic += 1 print ("3:", maxv, imax )
enumerate liefert Index und Element zusammen.