newbie: dictionary - howto get key value

Discussion in 'Python' started by G. Völkl, Mar 10, 2005.

  1. G. Völkl

    G. Völkl Guest

    Hello,

    I use a dictionary:

    phone = {'mike':10,'sue':8,'john':3}

    phone['mike'] --> 10

    I want to know who has number 3?

    3 --> 'john'

    How to get it in the python way ?

    Thanks
    Gerhard
     
    G. Völkl, Mar 10, 2005
    #1
    1. Advertising

  2. phone = {'mike':10,'sue':8,'john':3}
    print [key for key, value in phone.items() if value == 3]

    -> ['john']


    --
    Regards,

    Diez B. Roggisch
     
    Diez B. Roggisch, Mar 10, 2005
    #2
    1. Advertising

  3. G. Völkl wrote:
    > Hello,
    >
    > I use a dictionary:
    >
    > phone = {'mike':10,'sue':8,'john':3}
    >
    > phone['mike'] --> 10
    >
    > I want to know who has number 3?
    > 3 --> 'john'


    Note that you can have many keys with the same value:
    phone = {'mike':10,'sue':8,'john':3, 'jack': 3, 'helen' : 10}


    > How to get it in the python way ?


    simplest way I could think of in 30':
    def key_from_value(aDict, target):
    return [key for key, value in aDict.items() if value==target]

    key_from_value(phone, 3)
    --> ['john', 'jack']

    but this is a linear search, so not very efficient if phone is big.
    Then you may want to maintain a reversed index:
    (here again, simplest way I could think of)

    def rev_index(aDict):
    r = {}
    for key, value in aDict.items():
    if r.has_key(value):
    r[value].append(key)
    else:
    r[value] = [key]
    return r
    rev_phone = rev_index(phone)
    rev_phone
    --> {8: ['sue'], 10: ['helen', 'mike'], 3: ['john', 'jack']}

    {8: ['sue'], 10: ['helen', 'mike'], 3: ['john', 'jack']}

    rev_phone[3]
    --> ['john', 'jack']

    But now you've got another problem : you need to update the reversed
    index each time you modify the dictionary... Which would lead to writing
    a class extending dict, maintaining a reversed index, and exposing extra
    methods to handle this.

    But there may be a better way (someone else ?)

    --
    bruno desthuilliers
    python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
    p in ''.split('@')])"
     
    bruno modulix, Mar 10, 2005
    #3
  4. G. Völkl

    Tim Roberts Guest

    "G. Völkl" <> wrote:
    >
    >I use a dictionary:
    >
    >phone = {'mike':10,'sue':8,'john':3}
    >
    >phone['mike'] --> 10
    >
    >I want to know who has number 3?
    >
    >3 --> 'john'
    >
    >How to get it in the python way ?


    If you need to do this a lot, just keep two dictionaries, where the keys in
    each are the values in the other.

    reversephone = dict( zip( phone.values(), phone.keys() ) )
    --
    - Tim Roberts,
    Providenza & Boekelheide, Inc.
     
    Tim Roberts, Mar 12, 2005
    #4
  5. G. Völkl

    John Machin Guest

    bruno modulix wrote:
    > G. Völkl wrote:
    > > Hello,
    > >
    > > I use a dictionary:
    > >
    > > phone = {'mike':10,'sue':8,'john':3}
    > >
    > > phone['mike'] --> 10
    > >
    > > I want to know who has number 3?
    > > 3 --> 'john'

    >
    > Note that you can have many keys with the same value:
    > phone = {'mike':10,'sue':8,'john':3, 'jack': 3, 'helen' : 10}


    Of course in the real world using given name as a unique key is
    ludicrous: 'mike' is a.k.a. 'michael' (or 'mikhail' or 'michele' (which
    may be a typo for 'michelle')), and if there's only one 'sue' in your
    little black book you need to get out more :)
     
    John Machin, Mar 12, 2005
    #5
  6. G. Völkl

    Peter Hansen Guest

    John Machin wrote:
    >>G. Völkl wrote:
    >>>I use a dictionary:
    >>>phone = {'mike':10,'sue':8,'john':3}

    >
    > Of course in the real world using given name as a unique key is
    > ludicrous: 'mike' is a.k.a. 'michael' (or 'mikhail' or 'michele' (which
    > may be a typo for 'michelle')), and if there's only one 'sue' in your
    > little black book you need to get out more :)


    Maybe they're the names of his children... ;-)

    Of course, one could have multiple children with the
    same name under any or all of the following conditions:

    1. insanity (perhaps of the parents or the children?)
    2. remarriage (i.e. step-children)
    3. sheer forgetfulness
    4. laziness ("meet Brian, Brian, and Brian")

    This last is the closest I can come to making this post
    on-topic... sorry! :)

    -Peter
     
    Peter Hansen, Mar 12, 2005
    #6
  7. On Thu, 10 Mar 2005 18:56:41 +0100, bruno modulix <> wrote:

    >G. Völkl wrote:
    >> Hello,
    >>
    >> I use a dictionary:
    >>
    >> phone = {'mike':10,'sue':8,'john':3}
    >>
    >> phone['mike'] --> 10
    >>
    >> I want to know who has number 3?
    >> 3 --> 'john'

    >
    >Note that you can have many keys with the same value:
    >phone = {'mike':10,'sue':8,'john':3, 'jack': 3, 'helen' : 10}
    >
    >
    >> How to get it in the python way ?

    >
    >simplest way I could think of in 30':
    >def key_from_value(aDict, target):
    > return [key for key, value in aDict.items() if value==target]
    >
    >key_from_value(phone, 3)
    >--> ['john', 'jack']
    >
    >but this is a linear search, so not very efficient if phone is big.
    >Then you may want to maintain a reversed index:
    >(here again, simplest way I could think of)
    >
    >def rev_index(aDict):
    > r = {}
    > for key, value in aDict.items():
    > if r.has_key(value):
    > r[value].append(key)
    > else:
    > r[value] = [key]
    > return r
    >rev_phone = rev_index(phone)
    >rev_phone
    >--> {8: ['sue'], 10: ['helen', 'mike'], 3: ['john', 'jack']}
    >
    >{8: ['sue'], 10: ['helen', 'mike'], 3: ['john', 'jack']}
    >
    >rev_phone[3]
    >--> ['john', 'jack']
    >
    >But now you've got another problem : you need to update the reversed
    >index each time you modify the dictionary... Which would lead to writing
    >a class extending dict, maintaining a reversed index, and exposing extra
    >methods to handle this.
    >

    Not very tested:

    ----< twoway.py >--------------------
    class Twoway(dict):
    def __setitem__(self, name, number):
    dict.__setitem__(self, name, number)
    self.setdefault(number, []).append(name)
    def __delitem__(self, name):
    num = self[name]
    dict.__delitem__(self, name)
    self[num].remove(name)
    if not self[num]: del self[num]
    def __init__(self, src=None):
    if src is None: return
    dict.__init__(self, src)
    for name, num in self.items(): self.setdefault(num, []).append(name)

    if __name__ == '__main__':
    phone = Twoway({'mike':10,'sue':8,'john':3, 'jack': 3, 'helen' : 10})
    print 'jack:', phone['jack']
    print 'same phone as jack:', phone[phone['jack']]
    print 'deleting jack ...'; del phone['jack']
    print 'john:', phone['john']
    print phone
    -------------------------------------

    [13:05] C:\pywk\sovm>py24 twoway.py
    jack: 3
    same phone as jack: ['john', 'jack']
    deleting jack ...
    john: 3
    {'mike': 10, 3: ['john'], 8: ['sue'], 10: ['mike', 'helen'], 'sue': 8, 'helen': 10, 'john': 3}

    Regards,
    Bengt Richter
     
    Bengt Richter, Mar 12, 2005
    #7
  8. G. Völkl

    Joal Heagney Guest

    Tim Roberts wrote:
    > "G. Völkl" <> wrote:
    >
    >>I use a dictionary:
    >>
    >>phone = {'mike':10,'sue':8,'john':3}
    >>
    >>phone['mike'] --> 10
    >>
    >>I want to know who has number 3?
    >>
    >>3 --> 'john'
    >>
    >>How to get it in the python way ?

    >
    >
    > If you need to do this a lot, just keep two dictionaries, where the keys in
    > each are the values in the other.
    >
    > reversephone = dict( zip( phone.values(), phone.keys() ) )


    (Been away from python for a while, so forgive me if I'm asking a silly
    question.)
    Does python guarantee that the lists given by phone.values() and
    phone.keys() are in mutual order? Or is it possible that python will
    return the lists in different orders for .values() and .keys()?

    Joal
     
    Joal Heagney, Mar 14, 2005
    #8
  9. On Mon, 14 Mar 2005 05:02:25 GMT, Joal Heagney <> wrote:

    >Tim Roberts wrote:
    >> "G. Völkl" <> wrote:
    >>
    >>>I use a dictionary:
    >>>
    >>>phone = {'mike':10,'sue':8,'john':3}
    >>>
    >>>phone['mike'] --> 10
    >>>
    >>>I want to know who has number 3?
    >>>
    >>>3 --> 'john'
    >>>
    >>>How to get it in the python way ?

    >>
    >>
    >> If you need to do this a lot, just keep two dictionaries, where the keys in
    >> each are the values in the other.
    >>
    >> reversephone = dict( zip( phone.values(), phone.keys() ) )

    >
    >(Been away from python for a while, so forgive me if I'm asking a silly
    >question.)
    >Does python guarantee that the lists given by phone.values() and
    >phone.keys() are in mutual order? Or is it possible that python will
    >return the lists in different orders for .values() and .keys()?
    >

    Good question. I don't know. I hope so, but I would tend to write dict((v,k) for k,v in phone.items())
    to do the equivalent, but note that it only works if everyone has a different phone number.

    >>> dict((v,k) for k,v in {'sue':3, 'bob':4}.items())

    {3: 'sue', 4: 'bob'}
    >>> dict((v,k) for k,v in {'sue':3, 'bob':4, 'mike':4}.items())

    {3: 'sue', 4: 'bob'}

    Surprised at who got left out?
    >>> {'sue':3, 'bob':4, 'mike':4}.items()

    [('sue', 3), ('mike', 4), ('bob', 4)]

    Regards,
    Bengt Richter
     
    Bengt Richter, Mar 14, 2005
    #9
  10. G. Völkl

    Peter Otten Guest

    Joal Heagney wrote:

    > Does python guarantee that the lists given by phone.values() and
    > phone.keys() are in mutual order? Or is it possible that python will
    > return the lists in different orders for .values() and .keys()?


    Yes. Quoted from http://docs.python.org/lib/typesmapping.html:

    Keys and values are listed in an arbitrary order which is non-random, varies
    across Python implementations, and depends on the dictionary's history of
    insertions and deletions. If items(), keys(), values(), iteritems(),
    iterkeys(), and itervalues() are called with no intervening modifications
    to the dictionary, the lists will directly correspond. This allows the
    creation of (value, key) pairs using zip(): "pairs = zip(a.values(),
    a.keys())". The same relationship holds for the iterkeys() and itervalues()
    methods: "pairs = zip(a.itervalues(), a.iterkeys())" provides the same
    value for pairs. Another way to create the same list is "pairs = [(v, k)
    for (k, v) in a.iteritems()]".

    Peter
     
    Peter Otten, Mar 14, 2005
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Finney
    Replies:
    15
    Views:
    519
    John Machin
    Aug 6, 2003
  2. Replies:
    2
    Views:
    574
    bruno modulix
    Mar 10, 2005
  3. M P
    Replies:
    1
    Views:
    518
  4. Une bévue
    Replies:
    5
    Views:
    164
    Une bévue
    Aug 10, 2006
  5. Antonio Quinonez
    Replies:
    2
    Views:
    184
    Antonio Quinonez
    Aug 14, 2003
Loading...

Share This Page