2016-06-27 10 views
3

Ich war nur neugierig zu wissen, ob die folgende Schleife machbar mit der map() statt For-Schleife ist? Wenn ja bitte seien Sie freundlich genug, um zu zeigen, wie? oder Was ist der effizienteste Weg, um das Folgende zu tun?Python Wörterbuch Zuordnung mit Karte und Lambda

f = open('sample_list.txt').read().split('\n') 

val = lambda x: re.match('[a-zA-z0-9]+',x).group() if x else None 

for line in f: 
    if line.find('XYZ') == -1: 
     dict[val(line)]=0 
    else: 
     dict[val(line)]=1 

Dieses Programm liest eine Datei formatiert:

ABCD XYZ 
DEFG ABC 

dann eine dicionary mit dem ersten Wort als KEY erstellt und wenn der zweite Wert XYZ ist, dann wird es einen Wert von 1 sonst 0 zuweisen.

dh dict wird:

{'ABCD': 1, 'DEFG': 0} 

UPDATE:

I timed die Ansätze von @ shx2 vorgeschlagen und @arekolek Wörterbuch Verständnis ist schneller, und @ arekolek der Ansatz ist viel schneller als alles, da es nicht die val nicht verwendet() Lambda-Funktion ich erklärte.

der Code:

def a(): 
    return { 
    val(line) : 0 if line.find('XYZ') == -1 else 1 
    for line in f 
    } 

def b(): 
    return dict(map(lambda x: (x[0], int(x[1] == 'XYZ')), map(str.split, f))) 

def c(): 
    return {k: int(v == 'XYZ') for k, v in map(str.split, f)} 

print 'a='+timeit.timeit(a) 
print 'b='+timeit.timeit(b) 
print 'c='+timeit.timeit(c) 

Ergebnis:

a = 13.7737597283 
b = 6.82668938135 
c = 3.98859187269 

Dank sowohl das für die Ansicht :)

Antwort

1

mit einem Lambda:

dict(map(lambda x: (x[0], int(x[1] == 'XYZ')), map(str.split, f))) 

Oder:

dict(map(lambda k, v: (k, int(v == 'XYZ')), *map(str.split, f))) 

Wörterbuch Verständnis:

{k: int(v == 'XYZ') for k, v in map(str.split, f)} 
4

Bessere dict comprehension als map zu verwenden.

my_dict = { 
    val(line) : 0 if line.find('XYZ') == -1 else 1 
    for line in f 
} 

Einige Anmerkungen und Verbesserungen:

    :

    ein gute Variablennamen in Python
  • Alternativen zu dem komplizierten Ausdruck 0 if line.find('XYZ') == -1 else 1
    1. dict sind nicht

      kann wie folgt durchgeführt werden

    2. int(line.find('XYZ') != -1) (Konvertierung bool zu int)
    3. wenn Sie die Werte als bool s verlassen können: line.find('XYZ') != -1
    4. 'XYZ' in line (credit: @JonClements)
+0

Warum 'str.find' überhaupt hier -' wenn nicht ‚XYZ‘ in line' mehr pythonic ist, wenn Sie nur Eindämmung überprüfen möchten und nicht die zu verwende Index ... –

+0

@ JonClements richtig! Ich habe Ihren Vorschlag hinzugefügt – shx2

+1

Danke für Ihre Eingaben, das ist großartig. –