[Tutor] Second problem

Tim Peters tim_one@email.msn.com
Sun, 13 Jun 1999 18:56:08 -0400


[Jon Cosby]
> Another problem: The following prints out keys and values multiple times,
> once for each key with the same value; if three keys have the
> same value, it will print each three times.
> ...
>
> keys = dict.keys()
> vals = dict.values()
> vals.sort(comp)
> for v in vals:
>     for k in keys:
>         if dict[k] == v:
>             k = string.replace(k, dir + '\\', url)
>             print '<a href=\"' + k + '\">'
>             print '<b>', k, '</b></a>&nbsp;', v, counter(v), 'hits<br>'

It does that, of course, because that's what you told it to do <wink>:  for
each value, print out every key that maps to that value.  Let's make it
simpler (in part because you didn't give us your comp function or your dict,
so we *can't* run the code as posted):

>>> d = {'a': 1, 'b': 1, 'c':1}
>>> for v in d.values():
        for k in d.keys():
            if d[k] == v:
                print k, v

b 1
c 1
a 1
b 1
c 1
a 1
b 1
c 1
a 1
>>>

Think about what it does line by line, and you'll see it can't do anything
other than that.  If you want to see each pair only once, you need to get
away from nested loops:

>>> for k, v in d.items():
        print k, v

b 1
c 1
a 1
>>>

Now you're almost done:  wrap another function around your comp:

def paircomp(p1, p2):
    return comp(p1[1], p2[1])

and apply that to the items list:

x = d.items()
x.sort(paircomp)
for k, v in x:
    # Do your string fiddling and printing; the (k, v) pairs arrive
    # in increasing order of v, but in "random" order of k for equal
    # v; if that's not what you want, make paircomp smarter (the one
    # above simply ignores the k part).

orderedly y'rs  - tim