CppLearner
CppLearner

Reputation: 17040

Return the key name and value found in a dictionary given a tuple of names

I have a tuple with some names I want to match against one or more dictionaries.

t = ('A', 'B')
d1 = {'A': 'foo', 'C': 'bar'}
d2 = {'A': 'foo', 'B': 'foobar', 'C': 'bar'}

def f(dict):
    """
    Given t a tuple of names, find which name exist in the input
    dictionary dict, and return the name found and its value.
    If all names in the input tuple are found, pick the first one
    in the tuple instead.
    """
    keys = set(dict)
    matches = keys.intersection(t)
    if len(matches) == 2:
        name = t[0]
    else:
        name = matches.pop()
    value = dict[name]
    return name, value


print f(d1)
print f(d2)

The output is (A, foo) in both cases.

This is not a lot of code, but it involves converting to a set, and then do an intersection. I was looking into some functools and haven't found anything useful.

Is there a more optimized way doing this using the standard library or built-in functions that I am not aware of?

Thanks.

Upvotes: 0

Views: 142

Answers (4)

Elazar
Elazar

Reputation: 21595

for k in t:
    try:
        return k, dic[k]
    except KeyError:
        pass

If you (like me) don't like exceptions, and assuming None is not a legitimate value:

for k in t:
    res = dic.get(k)
    if res is not None:
        return k, res

Upvotes: 1

John La Rooy
John La Rooy

Reputation: 304147

def f(d):
    """
    Given t a tuple of names, find which name exist in the input
    dictionary d, and return the name found and its value.
    If all names in the input tuple are found, pick the first one
    in the tuple instead.
    """
    for item in ((k, d[k]) for k in t if k in d):
        return item
    return ()

Upvotes: 1

marianobianchi
marianobianchi

Reputation: 8488

The "try-except" variants are ok, but i don't think they are optimal for your case. If you know that t has only 2 values (i.e: len(t) == 2 is invariant/is always True), you can get advantage of this and try something like this:

def f(t, dic):
    if t[0] in dic:
        return t[0], dic[t[0]]
    elif t[1] in dic:
        return t[1], dic[t[1]]
    else: # Maybe any of t values are in dict
        return None, None

Upvotes: -1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798606

def f(d):
  try:
    return next((x, d[x]) for x in t if x in d)
  except StopIteration:
    return ()

Upvotes: 1

Related Questions