开发者

Determine position of values in dictionary, Python

There is a dictionary that may include keys starting from 0 and values: a, b, c, d, e. Each time the values may be assigned to different keys keys. Size of the dictionary may change as well.

I am interested in two values. Let's call them b and d. Is there any algorithm that determine situations when b appears earlier than d (i.e. b's key is smaller than d's) and when d appears earlier than b (i.e. d's key is is smaller than b'开发者_C百科s)?


A dictionary has no order. So your wording "b's key is smaller than d's" is the right one.

Now, it looks like you could swap keys and values...


If the values are hashable then you could generate a reverse dictionary and check the values. Otherwise, you'll need to brute-force it.

def dictfind(din, tsent, fsent):
  for k in sorted(din.iterkeys()):
    if din[k] == tsent:
      return True
    if din[k] == fsent:
      return False
  else:
    raise ValueError('No match found')

D = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e'}

print dictfind(D, 'b', 'd')


Dictionaries are unordered sets of key-value pairs. dict.keys() need not produce the same output always. Can't you do what you want with lists?


First create your dictionary

>>> import random
>>> keys = range(5)
>>> random.shuffle(keys)
>>> d=dict(zip(keys, "abcde"))
>>> d
{0: 'd', 1: 'c', 2: 'e', 3: 'b', 4: 'a'}

Now create a dictionary using the keys of d as the values and the values of d as the keys

>>> rev_d = dict((v,k) for k,v in d.items())

Your comparisons are now just regular dictionary lookups

>>> rev_d['b'] > rev_d['d']
True


From your comment on gnibbler's answer, it sounds like when there are multiple occurrences of a value, you only care about the earliest appearing one. In that case, the swapped (value, key)-dictionary suggested can still be used, but with minor modification to how you build it.

xs = {0: 'a', 1: 'b', 2: 'a'}
ys = {}
for k, v in xs.iteritems():
    if v not in ys or k < ys[v]:
        ys[v] = k

You could then define a function that tells you which of two values maps to a smaller index:

def earlier(index_map, a, b):
    """Returns `a` or `b` depending on which has a smaller value in `index_map`.

    Returns `None` if either `a` or `b` is not in `index_map`.

    """
    if a not in index_map or b not in index_map:
        return None

    if index_map[a] < index_map[b]:
        return a

    return b

Usage:

print earlier(ys, 'a', 'b')

There are some subtleties here whose resolution depends on your particular problem.

  • What should happen if a or b is not in index_map? Right now we return None.
  • What should happen if index_map[a] == index_map[b]? From your comments it sounds like this may not happen in your case, but you should consider it. Right now we return b.
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜