[Tutor] Floats as dictionary keys

Jeff Shannon jeff@ccvcorp.com
Tue Apr 1 14:04:01 2003


Brian Christopher Robinson wrote:

> Is there any way to force the dictionary not to stringize my float 
> values? 


It doesn't -- you're doing that yourself somehow.  Cutting and pasting 
the results you showed into another dictionary gives me this:

 >>> pprint.pprint(averagesfirst)
{3.3885999999999998: '1d 4',
 4.2656999999999998: '1d 6',
 4.6638999999999999: '2d 4',
 5.0884999999999998: '1d 8',
 5.6045999999999996: '3d 4',
 5.7830000000000004: '2d 6',
 6.1249000000000002: '1d10',
 6.2816999999999998: '4d 4',
 6.8376000000000001: '3d 6',
 7.0937999999999999: '2d 8',
 7.1222000000000003: '1d12',
 7.6048999999999998: '4d 6',
 8.2827000000000002: '3d 8',
 8.3605: '2d10',
 9.1555999999999997: '4d 8',
 9.6381999999999994: '3d10',
 9.7449999999999992: '2d12',
 10.714700000000001: '4d10',
 11.170199999999999: '3d12',
 12.272500000000001: '4d12'}
 >>>

Now, using essentially the same code as you showed, I get them sorted in 
proper numeric order:

 >>> def GetSortedKeys(adict):
...     keys = adict.keys()
...     keys.sort()
...     return keys
...
 >>> for key in GetSortedKeys(averagesfirst):
...     print '%4s : %8.5f' % (averagesfirst[key], key)
...    
1d 4 :  3.38860
1d 6 :  4.26570
2d 4 :  4.66390
1d 8 :  5.08850
3d 4 :  5.60460
2d 6 :  5.78300
1d10 :  6.12490
4d 4 :  6.28170
3d 6 :  6.83760
2d 8 :  7.09380
1d12 :  7.12220
4d 6 :  7.60490
3d 8 :  8.28270
2d10 :  8.36050
4d 8 :  9.15560
3d10 :  9.63820
2d12 :  9.74500
4d10 : 10.71470
3d12 : 11.17020
4d12 : 12.27250
 >>>

I'm not sure why the results you show are different -- perhaps they were 
generated with a different version of the code than what you posted?  In 
any case, though, unless you're doing more with these dictionaries 
later, you might be better off generating a single list or dictionary of 
two-tuples, which might be easier to fiddle with.

 >>> averages = {}
 >>> for dice in range(1,5):    # note the use of a start param for range
...     for sides in [4, 6, 8, 10, 12]:
...         avg = findAverage(dice, sides)
...         diceString = "%dd%2d" % (dice, sides)
...         averages[diceString] = (avg, diceString)
...
 >>> averageslist = averages.values()
 >>> averageslist.sort()
 >>> for avg, dice in averageslist:
...     print '%4s : %8.5f' % (dice, avg)
...
1d 4 :  3.38860
1d 6 :  4.26570
2d 4 :  4.66390
1d 8 :  5.08850
3d 4 :  5.60460
2d 6 :  5.78300
1d10 :  6.12490
4d 4 :  6.28170
3d 6 :  6.83760
2d 8 :  7.09380
1d12 :  7.12220
4d 6 :  7.60490
3d 8 :  8.28270
2d10 :  8.36050
4d 8 :  9.15560
3d10 :  9.63820
2d12 :  9.74500
4d10 : 10.71470
3d12 : 11.17020
4d12 : 12.27250
 >>> templist = [(value, key) for key, value in averageslist]
 >>> templist.sort()
 >>> for dice, avg in templist:
...     print '%4s : %8.5f' % (dice, avg)
...
1d 4 :  3.38860
1d 6 :  4.26570
1d 8 :  5.08850
1d10 :  6.12490
1d12 :  7.12220
2d 4 :  4.66390
2d 6 :  5.78300
2d 8 :  7.09380
2d10 :  8.36050
2d12 :  9.74500
3d 4 :  5.60460
3d 6 :  6.83760
3d 8 :  8.28270
3d10 :  9.63820
3d12 : 11.17020
4d 4 :  6.28170
4d 6 :  7.60490
4d 8 :  9.15560
4d10 : 10.71470
4d12 : 12.27250
 >>>

Putting both results into a single list or dict gives you a little more 
flexibility in dealing with the data later,.

Jeff Shannon
Technician/Programmer
Credit International