5

I was just curious to know if the following loop is doable with the map() rather than using for loop ? If yes please be kind enough to show how ? or what's the most efficient way to do the following ?

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

This program reads a file formatted as :

ABCD XYZ 
DEFG ABC

then creates a dicionary with first word as KEY and if the second value is XYZ then it will assign a value of 1 else 0.

i.e dict will be :

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

UPDATE :

I timed the approaches suggested by @shx2 and @arekolek dictionary comprehension is faster, and @arekolek's approach is way faster than anything as it doesn't use the val() lambda function i declared.

the 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)

result :

a = 13.7737597283
b = 6.82668938135
c = 3.98859187269

Thanks both for showing this :)

2 Answers 2

5

Better to use dict comprehension than map.

Can be done like this:

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

Some notes and improvements:

  1. dict is not a good variable name in python
  2. Alternatives to the complicated expression 0 if line.find('XYZ') == -1 else 1:
    • int(line.find('XYZ') != -1) (converting bool to int)
    • if you can leave the values as bools: line.find('XYZ') != -1
    • 'XYZ' in line (credit: @JonClements)
Sign up to request clarification or add additional context in comments.

2 Comments

Why use str.find at all here - if not 'XYZ' in line is more pythonic if you only want to check containment and aren't going to use the index...
Thanks for your inputs, this is great.
1

With a lambda:

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

Or:

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

Dictionary comprehension:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.