<HTML><BODY style="word-wrap: break-word; -khtml-nbsp-mode: space; -khtml-line-break: after-white-space; "><BR><DIV><DIV>On 2007-08-01, at 06:50, Astan Chee wrote:</DIV><BR class="Apple-interchange-newline"><BLOCKQUOTE type="cite"> Hi,<BR> I have a dictionary which looks something like this:<BR> <FONT face="Courier New"><BR> elem = {"co":[1,2,3],"cp":[3,2,1],"pp":[5,6,7],"cl":[1,2,3],"qw":[6,7,8],"qa":[8,7,6]}</FONT><BR> <BR> what Im trying to do is find all keys in the list that have the same value and delete those (except one); thereby removing all redundant keys so that the above dict will look like this:<BR> <FONT face="Courier New"><BR> elem = {"co":[1,2,3],"pp":[5,6,7],"qa":[8,7,6]}</FONT><BR> <BR> my code so far looks like this:<BR> <BR> <FONT face="Courier New, Courier, monospace">for out1 in elem.keys():<BR>     for out2 in elem.keys():<BR>         if out1 != out2:<BR>             elem[out1].sort()<BR>             elem[out2].sort()<BR>             if elem[out1] == elem[out2]:<BR>                 del elem[out1]<BR> <BR> </FONT>This returns in a KeyError exception when sorting. What am I missing here? <BR class="khtml-block-placeholder"></BLOCKQUOTE><BR></DIV><DIV>Consider a dict {'a': [1], 'b': [1], 'c': [1]}.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>First time we reach the innerloop, out1 == 'a'. Then we iterate over the list ['a', 'b', 'c'].</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>'a' is skipped. At 'b', we remove 'a' from the dictionary. And then it all goes wrong.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>The last time we go through the inner loop, out1 is still 'a' -- an element which does not exist in the dictionary anymore. Then your attempts to reference it fail at both the sorting and comparison stages. You should break out of the inner loop immediately after you've deleted the item or delete out2 instead..</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>Furthermore, the algorithm is somewhat inefficient due to the fact that it sorts the lists O(n^2) times when you only need to do them n times. If your data allows it, you might like to use sets instead of lists. This would avoid the need to sort the lists.</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>However, here is a very quick version that works in my tests:</DIV><DIV>for out_list in elem.values():</DIV><DIV>    out_list.sort()</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>for out1 in elem.keys():</DIV><DIV>    for out2 in elem.keys():</DIV><DIV>        if out1 != out2 and elem[out1] == elem[out2]:</DIV><DIV>            del elem[out1]</DIV><DIV>            break</DIV><DIV><BR class="khtml-block-placeholder"></DIV><DIV>There are probably several ways to improve on that, however.</DIV><BR><DIV> <P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">--<SPAN class="Apple-converted-space"> </SPAN></FONT></P> <P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">[ <A href="mailto:ars@iki.fi">ars@iki.fi</A> &lt;*&gt; Antti Rasinen ]</FONT></P> <P style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px"><BR></P> <P style="margin: 0.0px 0.0px 0.0px 0.0px"><FONT face="Helvetica" size="3" style="font: 12.0px Helvetica">"Pay the man his wage, he's making paper to fuel the Information Age."</FONT></P> <BR class="Apple-interchange-newline"> </DIV><BR></BODY></HTML>