Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #9932 > unrolled thread

Pythonic way with more than one max possible

Started byCM <cmpython@gmail.com>
First post2011-07-19 20:17 -0700
Last post2011-07-20 13:25 -0700
Articles 8 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Pythonic way with more than one max possible CM <cmpython@gmail.com> - 2011-07-19 20:17 -0700
    Re: Pythonic way with more than one max possible Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-07-20 14:19 +1000
      Re: Pythonic way with more than one max possible Thomas Jollans <t@jollybox.de> - 2011-07-20 12:51 +0200
    Re: Pythonic way with more than one max possible Chris Rebert <clp2@rebertia.com> - 2011-07-19 21:33 -0700
    Re: Pythonic way with more than one max possible CM <cmpython@gmail.com> - 2011-07-19 22:10 -0700
      Re: Pythonic way with more than one max possible woooee <woooee@gmail.com> - 2011-07-19 22:37 -0700
      Re: Pythonic way with more than one max possible Chris Rebert <clp2@rebertia.com> - 2011-07-19 23:56 -0700
    Re: Pythonic way with more than one max possible CM <cmpython@gmail.com> - 2011-07-20 13:25 -0700

#9932 — Pythonic way with more than one max possible

FromCM <cmpython@gmail.com>
Date2011-07-19 20:17 -0700
SubjectPythonic way with more than one max possible
Message-ID<acfc6e53-fd3c-4404-9314-aa01dc35c0d7@a31g2000vbt.googlegroups.com>
I have three items in a dict, like this:

the_dict = {'a':1, 'b':2, 'c':3}

but the vals could be anything.  I want to configure something else
based on the "winner" of such a dict, with these rules:

1. In this dict, if there is a UNIQUE max value, that's the winner.
2. If there are any TIES for max value, b is the winner by default.

The problem for me, as I see it, is I don't know any elegant ways to
do this in Python.  The max(dict) function doesn't distinguish between
unique and non-unique maxes.  I could go through and test the various
possibilities (to see if the max value had any matches in the other
values), but, knowing Python, there is probably something close to
"one way to do it".  Any suggestions?

Thanks,
Che

[toc] | [next] | [standalone]


#9933

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-07-20 14:19 +1000
Message-ID<4e265748$0$29970$c3e8da3$5496439d@news.astraweb.com>
In reply to#9932
On Wed, 20 Jul 2011 01:17 pm CM wrote:

> I have three items in a dict, like this:
> 
> the_dict = {'a':1, 'b':2, 'c':3}
> 
> but the vals could be anything.  I want to configure something else
> based on the "winner" of such a dict, with these rules:
> 
> 1. In this dict, if there is a UNIQUE max value, that's the winner.
> 2. If there are any TIES for max value, b is the winner by default.
> 
> The problem for me, as I see it, is I don't know any elegant ways to
> do this in Python.  The max(dict) function doesn't distinguish between
> unique and non-unique maxes.  I could go through and test the various
> possibilities (to see if the max value had any matches in the other
> values), but, knowing Python, there is probably something close to
> "one way to do it".  Any suggestions?

# Untested.
def get_winner(adict):
    values = sorted(adict.values(), reverse=True)
    if values[0] == values[1]:
        return adict['b']
    else:
        return values[0]

Assumes that adict has at least two items. May be slow if it has millions of
items.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#9957

FromThomas Jollans <t@jollybox.de>
Date2011-07-20 12:51 +0200
Message-ID<mailman.1287.1311159102.1164.python-list@python.org>
In reply to#9933
On 20/07/11 06:19, Steven D'Aprano wrote:
> On Wed, 20 Jul 2011 01:17 pm CM wrote:
> 
>> I have three items in a dict, like this:
>>
>> the_dict = {'a':1, 'b':2, 'c':3}
>>
>> but the vals could be anything.  I want to configure something else
>> based on the "winner" of such a dict, with these rules:
>>
>> 1. In this dict, if there is a UNIQUE max value, that's the winner.
>> 2. If there are any TIES for max value, b is the winner by default.
>>
>> The problem for me, as I see it, is I don't know any elegant ways to
>> do this in Python.  The max(dict) function doesn't distinguish between
>> unique and non-unique maxes.  I could go through and test the various
>> possibilities (to see if the max value had any matches in the other
>> values), but, knowing Python, there is probably something close to
>> "one way to do it".  Any suggestions?
> 
> # Untested.
> def get_winner(adict):
>     values = sorted(adict.values(), reverse=True)
>     if values[0] == values[1]:
>         return adict['b']
>     else:
>         return values[0]

# Untested, with keys:
def get_winner(adict):
    values = sorted(adict.items(), reverse=True,
                    key=(lambda k_v: k_v[1]))
    if values[0][1] == values[1][1]:
        return 'b'
    else:
        return values[0][0]

> 
> Assumes that adict has at least two items. May be slow if it has millions of
> items.
> 
> 

[toc] | [prev] | [next] | [standalone]


#9935

FromChris Rebert <clp2@rebertia.com>
Date2011-07-19 21:33 -0700
Message-ID<mailman.1278.1311136401.1164.python-list@python.org>
In reply to#9932
On Tue, Jul 19, 2011 at 8:17 PM, CM <cmpython@gmail.com> wrote:
> I have three items in a dict, like this:
>
> the_dict = {'a':1, 'b':2, 'c':3}
>
> but the vals could be anything.  I want to configure something else
> based on the "winner" of such a dict, with these rules:
>
> 1. In this dict, if there is a UNIQUE max value, that's the winner.
> 2. If there are any TIES for max value, b is the winner by default.

Er, for (2), you mean b's /value/ is the winner, right?

> The problem for me, as I see it, is I don't know any elegant ways to
> do this in Python.  The max(dict) function doesn't distinguish between
> unique and non-unique maxes.  I could go through and test the various
> possibilities (to see if the max value had any matches in the other
> values), but, knowing Python, there is probably something close to
> "one way to do it".  Any suggestions?

# presumes at least 2 items
from heapq import nlargest
winner, runner_up = nlargest(2, the_dict.itervalues())
if winner == runner_up:
    winner = the_dict['b']

Cheers,
Chris
--
http://rebertia.com

[toc] | [prev] | [next] | [standalone]


#9936

FromCM <cmpython@gmail.com>
Date2011-07-19 22:10 -0700
Message-ID<6e96527b-e41c-4f1a-b829-a2fa7648eaa3@t9g2000vbs.googlegroups.com>
In reply to#9932
On Jul 19, 11:17 pm, CM <cmpyt...@gmail.com> wrote:
> I have three items in a dict, like this:
>
> the_dict = {'a':1, 'b':2, 'c':3}
>
> but the vals could be anything.  I want to configure something else
> based on the "winner" of such a dict, with these rules:
>
> 1. In this dict, if there is a UNIQUE max value, that's the winner.
> 2. If there are any TIES for max value, b is the winner by default.
>

Thank you to Steven and Chris for the answers.  Very elegant.

I realize, now though, (and Chris asked about this) that I was
imprecise in my
rules.  They really should be stated as:

1. In this dict, if there is a UNIQUE max value, then its *key* is the
winner.
2. If there are any TIES for max value, then the *key* 'b' is the
winner by default.

The point is, I am trying to determine the name of the winning
category, either
'a', 'b', or 'c', not the value of its winning score.

So in your solutions there is sorting by values, which makes sense.
But how
can I go back to keys from there?  Sorry for the mistake (but even so,
I learned
something already).

Thanks again,
Che

[toc] | [prev] | [next] | [standalone]


#9937

Fromwoooee <woooee@gmail.com>
Date2011-07-19 22:37 -0700
Message-ID<4915fe3e-2521-4456-88ed-0ce9c945bccf@g5g2000prn.googlegroups.com>
In reply to#9936
> 1. In this dict, if there is a UNIQUE max value, then its *key* is the
> winner.
> 2. If there are any TIES for max value, then the *key* 'b' is the
> winner by default.

This will store the max value(s) in a list.  In case of a tie, you can
take the first value in the list, but it may be different than 'b'
since dictionary keys are in hash order, not in the order they were
entered.  You can decide if you want the smallest key, or whatever
criterion is best.

the_dict = {'a':1, 'b':2, 'c':0, 'd':1, 'a0':2}
winners = [['*', -999]]
for key in the_dict:
    max_value = winners[0][1]  ## only lookup once
    dict_value = the_dict[key] ##  "     "     "
    if dict_value > max_value:
        winners = [[key, dict_value]]
    elif dict_value == max_value:
        winners.append([key, dict_value])

print winners

[toc] | [prev] | [next] | [standalone]


#9942

FromChris Rebert <clp2@rebertia.com>
Date2011-07-19 23:56 -0700
Message-ID<mailman.1280.1311145014.1164.python-list@python.org>
In reply to#9936
On Tue, Jul 19, 2011 at 10:10 PM, CM <cmpython@gmail.com> wrote:
> On Jul 19, 11:17 pm, CM <cmpyt...@gmail.com> wrote:
>> I have three items in a dict, like this:
>>
>> the_dict = {'a':1, 'b':2, 'c':3}
>>
>> but the vals could be anything.  I want to configure something else
>> based on the "winner" of such a dict, with these rules:
<snip>
> I realize, now though, (and Chris asked about this) that I was
> imprecise in my
> rules.  They really should be stated as:
>
> 1. In this dict, if there is a UNIQUE max value, then its *key* is the
> winner.
> 2. If there are any TIES for max value, then the *key* 'b' is the
> winner by default.
>
> The point is, I am trying to determine the name of the winning
> category, either
> 'a', 'b', or 'c', not the value of its winning score.
>
> So in your solutions there is sorting by values, which makes sense.
> But how
> can I go back to keys from there?  Sorry for the mistake (but even so,
> I learned
> something already).

# still presumes at least 2 items
from heapq import nlargest
winner, runner_up = nlargest(2, the_dict, lambda k: the_dict[k])
if the_dict[winner] == the_dict[runner_up]:
   winner = 'b'

Cheers,
Chris

[toc] | [prev] | [next] | [standalone]


#9990

FromCM <cmpython@gmail.com>
Date2011-07-20 13:25 -0700
Message-ID<1aa777f4-5960-4b97-8ba6-5111ad4b0aff@g2g2000vbl.googlegroups.com>
In reply to#9932
Thanks, everyone.  Very helpful!

Che

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web