user3082173
user3082173

Reputation: 1

How can I convert those two loops using map and filter?

I try to write this code using the map and filter built-in functions. How can I do it?

for elem in courses_dict:
    for ele in types:
            for element in types[ele]:
                if elem==element:
                    courses_dict[elem]+=factors[ele]

Upvotes: 0

Views: 113

Answers (1)

jfs
jfs

Reputation: 414315

Here's a modified code from your question that assumes that types is a mapping: type_id -> types:

for course_id in courses_dict:
    for type_id, type_values in types.items(): # assume `types` is a mapping
        for type in type_values:
            if course_id == type:
               courses_dict[course_id] += factors[type_id]

You could make the inner loop implicit:

for course_id in courses_dict:
    for type_id, type_values in types.items(): # assume `types` is a mapping
        count = type_values.count(course_id) # assume `.count` is present
        if count: # course_id in type_values
           courses_dict[course_id] += count*factors[type_id]

It type_values has .count() method e.g., it is a list.

The explicit loops are fine as is. If you want to see how it can be written using map, filter for academic reasons:

from collection import deque
from itertools import product, starmap

pairs = product(courses_dict, types)
# course_id == p[0] and type_id == p[1]
triples = map(lambda p: (types[p[1]].count(p[0]),) + p, pairs)
triples = filter(lambda t: t[0], triples) # count == t[0]

def increment(count, course_id, type_id):
    courses_dict[course_id] += count * factors[type_id] 

deque(starmap(increment, triples), maxlen=0) # "consume" recipe from itertools

If I'd known what your input values: courses_dict, types, factors contain; better more concrete names could be used instead of the above abstract one. But it would still be ugly.

Upvotes: 1

Related Questions