frazman
frazman

Reputation: 33263

Pythonic way to manipulate same dictionary

A very naive question.. I have the following function:

def vectorize(pos, neg):
    vec = {item_id:1 for item_id in pos}
    for item_id in neg:
        vec[item_id] = 0
    return vec

Example:

>>> print vectorize([1, 2] [3, 200, 201, 202])
{1: 1, 2: 1, 3: 0, 200: 0, 201: 0, 202: 0}

I feel, this is too verbose in python.. Is there a more pythonic way to do this... Basically, I am returning a dictionary whose values are 1 if its in pos (list) and 0 otherwise?

Upvotes: 3

Views: 91

Answers (4)

martineau
martineau

Reputation: 123473

This would be Pythonic, in the sense of being relatively short and making maximum use of the language's features:

def vectorize(pos, neg):
    pos_set = set(pos)
    return {item_id: int(item_id in pos_set) for item_id in set(pos+neg)}

print vectorize([1, 2], [3, 200, 201, 202])

Upvotes: 1

5gon12eder
5gon12eder

Reputation: 25429

You could use

vec = {item_id : 0 if item_id in neg else 1 for item_id in pos}

Note however that the lookup item_id in neg won't be efficient if neg is a list (as opposed to a set).

Update: After seeing your expected output.

Note that the above does not insert 0s for items that are only in neg. If you want that too, the following one-liner could be used.

vec = dict([(item_id, 1) for item_id in pos] + [(item_id, 0) for item_id in neg])

If you want to avoid creating the two temporary lists, itertools.chain could help.

from itertools import chain
vec = dict(chain(((item_id, 1) for item_id in pos), ((item_id, 0) for item_id in neg)))

Upvotes: 1

Savir
Savir

Reputation: 18418

I'm not particularly sure if this is more pythonic... Maybe a little bit more efficient? Dunno, really

pos = [1, 2, 3, 4]
neg = [5, 6, 7, 8]

def vectorize(pos, neg):
    vec = dict.fromkeys(pos, 1)
    vec.update(dict.fromkeys(neg, 0))
    return vec

print vectorize(pos, neg)

Outputs:

{1: 1, 2: 1, 3: 1, 4: 1, 5: 0, 6: 0, 7: 0, 8: 0}

But I like your way too... Just giving an idea here.

Upvotes: 3

Bill Lynch
Bill Lynch

Reputation: 81936

I'd probably just do:

def vectorize(pos, neg):
    vec = {}
    vec.update((item, 1) for item in pos)
    vec.update((item, 0) for item in neg)
    return vec

But your code is fine as well.

Upvotes: 1

Related Questions