473,320 Members | 1,840 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

False and 0 in the same dictionary

I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:

How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.
As I have learnt, 0 and False both hash to the same value (same for 1
and True).
>>b = {0:'xyz', False:'abc'}
b
{0: 'abc'} # Am I the only one who thinks this is weird?

This obviously stems from the fact that 0 == False but 0 is not False
etc. etc.

That doesn't help my case where I need to distinguish between the two

The same issue applies in a list:

Suppose I do:
>>a = [0, 1, True, False]
a.index(False)
0

Wha??? Help.
Nov 4 '08 #1
14 3303
Prateek <su*****@gmail.comwrote:
I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:

How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.
How about using (x, type(x)) as the key instead of just x?

Nov 4 '08 #2
On Nov 5, 1:52*am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
Prateek <sure...@gmail.comwrote:
I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:
How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.

How about using (x, type(x)) as the key instead of just x?
Yup. I thought of that. Although it seems kinda unpythonic to do so.
Especially since the dictionary is basically a cache mostly containing
strings. Adding all the memory overhead for the extra tuples seems
like a waste just for those four keys.

Is there a better way?
I also thought of using a custom __eq__ method in a custom class
which extends the dict type but decided that was even worse.

Prateek
Nov 4 '08 #3
On Nov 4, 4:21*pm, Prateek <sure...@gmail.comwrote:
On Nov 5, 1:52*am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
Prateek <sure...@gmail.comwrote:
I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:
How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.
How about using (x, type(x)) as the key instead of just x?

Yup. I thought of that. Although it seems kinda unpythonic to do so.
Especially since the dictionary is basically a cache mostly containing
strings. Adding all the memory overhead for the extra tuples seems
like a waste just for those four keys.

Is there a better way?
I also thought of using a custom __eq__ *method in a custom class
which extends the dict type but decided that was even worse.

Prateek
Hmm, my original reply didn't show up.

I'm curious as to what you're trying to accomplish.

Bear in mind that I type this response not knowing your application.
While Python is not a statically typed language, 0 and False are
essentially different types (int and bool). Storing them both as keys
of a dictionary just doesn't seem like a good design.
Nov 4 '08 #4
Prateek <su*****@gmail.comwrites:
On Nov 5, 1:52*am, Duncan Booth <duncan.bo...@invalid.invalidwrote:
>Prateek <sure...@gmail.comwrote:
I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:
How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.

How about using (x, type(x)) as the key instead of just x?

Yup. I thought of that. Although it seems kinda unpythonic to do so.
Especially since the dictionary is basically a cache mostly containing
strings. Adding all the memory overhead for the extra tuples seems
like a waste just for those four keys.

Is there a better way?
I also thought of using a custom __eq__ method in a custom class
which extends the dict type but decided that was even worse.

Prateek
You could use currying on Duncan's solution :). It would
give something like this (minimal implementation):

from collections import defaultdict

class DictByType(object):
def __init__(self):
self.dicts = defaultdict(dict)
def __setitem__(self, key, val):
self.dicts[type(key)][key] = val
def __getitem__(self, key):
return self.dicts[type(key)][key]
Then:
>>d = DictByType()
d[1]='foo'
d[True]='bar'
d[1.0] = 'foobar'
d[1], d[True], d[1.0]
('foo', 'bar', 'foobar')

If, as seems to be the case, you have many keys with few types, then the
memory overhead will be smaller. Access time might suffer though.

--
Arnaud
Nov 4 '08 #5
Prateek <su*****@gmail.comwrites:
>b = {0:'xyz', False:'abc'}
b
{0: 'abc'} # Am I the only one who thinks this is weird?
You're not the only one; I consider this a wart in Python.

False and True should be discrete values that don't compare equal with
any other value, not even ones that evaluate to boolean False or True.
>>False == []
False
>>False == {}
False
>>False == ''
False
>>False == 0
True

This is an artifact of the fact that ‘bool’ is a subclass of ‘int’,
and that ‘False’ is implemented such that it has the same hash as ‘0’:
>>isinstance(False, int)
True
>>hash(False) == hash(0)
True

The above is a legacy of the original lack of a boolean type in
Python, but it's confusing and IMO unnecessary these days. It should
be enough that they all evaluate to False in a boolean context:
>>bool([])
False
>>bool({})
False
>>bool('')
False
>>bool(0)
False

PEP 285 <URL:http://www.python.org/dev/peps/pep-0285>, that introduced
the ‘bool’ type, addresses this issue:

In an ideal world, bool might be better implemented as a
separate integer type that knows how to perform mixed-mode
arithmetic. However, inheriting bool from int eases the
implementation enormously (in part since all C code that calls
PyInt_Check() will continue to work -- this returns true for
subclasses of int). Also, I believe this is right in terms of
substitutability: code that requires an int can be fed a bool
and it will behave the same as 0 or 1. Code that requires a
bool may not work when it is given an int; for example, 3 & 4
is 0, but both 3 and 4 are true when considered as truth
values.

I wonder if any of that is relevant any more.

What does backward-compatibility-is-less-important Python 3 do (I
don't have it installed)? Is there a later PEP that I've missed which
finally makes ‘bool’ a type independent from ‘int’?

--
\ “A ‘No’ uttered from deepest conviction is better and greater |
`\ than a ‘Yes’ merely uttered to please, or what is worse, to |
_o__) avoid trouble.” —Mahatma Gandhi |
Ben Finney
Nov 4 '08 #6
"Prateek" <su*****@gmail.comwrote:
>b = {0:'xyz', False:'abc'}
b
{0: 'abc'} # Am I the only one who thinks this is weird?
No. This was discussed before on this list, and that discussion
referenced (if I recall correctly) the discussion on python-dev
at the time the decision was taken.

If my name were Laura Creighton, I would now say:

"I told you so!"

Now I have to weigh my words carefully to make sure I
am not misunderstood:

You are screwed!

- Hendrik

Nov 5 '08 #7
Ben Finney:
Is there a later PEP that I've missed which
finally makes bool a type independent from int?
In a tidy language like an ObjectPascal or Java bools and integers are
different types.

In Python if bools become distinct from integers you have to rewrite
things like:
sum(el == val for el in iterable)
as:
sum(1 for el in iterable if el == val)

In the past here I have stated that boolean operators should return
only boolean values, and I believe it still. Because doing otherwise
is quite confusing.

But in practice I have seen that while being a little untidy, having
bools as subtype of int doesn't lead to much bugs, and it has few
practical advantages. So purity isn't that useful here.

Having an iterable that contains both ints and bools isn't too much
common, because while Python isn't statically typed, in practice most
of the times in most Python programs types are uniform and predictable
(that's why ShedSkin can work).

And even if you have a list that contains bools and integers mixed,
then having to tell them apart (by hashing, etc) is quite uncommon, I
think I have never had to do it in 2-3 years. So maybe is that code
that is doing something messy, so maybe is that code that has to
change and become more tidy, and not the language itself :-)

Bye,
bearophile
Nov 5 '08 #8
Prateek:
How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.
Why do you have to do that? What's the problem you have to solve?
Maybe (probably) there are better or more clean alternative solutions.

Bye,
bearophile
Nov 5 '08 #9
On Wed, 05 Nov 2008 04:22:32 -0800, bearophileHUGS wrote:
In Python if bools become distinct from integers you have to rewrite
things like:
sum(el == val for el in iterable)
as:
sum(1 for el in iterable if el == val)
I would expect that you can still "cast" `bool`\s to `int`\s then.
Sometimes I write it as

sum(int(el == val) for el in iterable)

just for clarity what the intent is.

Ciao,
Marc 'BlackJack' Rintsch
Nov 5 '08 #10
On Nov 4, 3:48*pm, Prateek <sure...@gmail.comwrote:
I've been using Python for a while (4 years) so I feel like a moron
writing this post because I think I should know the answer to this
question:

How do I make a dictionary which has distinct key-value pairs for 0,
False, 1 and True.
As I have learnt, 0 and False both hash to the same value (same for 1
and True).
>b = {0:'xyz', False:'abc'}
b

{0: 'abc'} *# Am I the only one who thinks this is weird?

This obviously stems from the fact that 0 == False but 0 is not False
etc. etc.

That doesn't help my case where I need to distinguish between the two

The same issue applies in a list:

Suppose I do:
>a = [0, 1, True, False]
a.index(False)

0

Wha??? Help.

Let me suggest using surrogate objects instead of True and False:

class TrueObject(object):
def __nonzero__(self):
return True

class FalseObject(object):
def __nonzero__(self):
return False

DistinctTrue = TrueObject()
DistinctFalse = FalseObject()
If that doesn't work and you really need the actual True and False
objects to be distinct, it's not too hard to special case a dict to
get it:

class special_dict(dict):
def __init__(self,*args,**kwargs):
self.true_surrogate = object()
self.false_surrogate = object()
super(special_dict,self).__init__(*args,**kwargs)
def __getitem__(self,value):
if value is True:
value = self.true_surrogate
elif value is False:
value = self.false_surrogate
super(special_dict,self).__getitem__(value)
## etc.
Carl Banks
Nov 5 '08 #11
Prateek <su*****@gmail.comwrites:
How about using (x, type(x)) as the key instead of just x?
Yup. I thought of that. Although it seems kinda unpythonic to do so.
Especially since the dictionary is basically a cache mostly containing
strings. Adding all the memory overhead for the extra tuples seems
like a waste just for those four keys.
You could use a second dict for the other type:

def lookup(x):
if x in dict1: return dict1[x]
return dict2[x]

dict1 would have the 4 special keys and dict2 would have the regular
keys.
Nov 7 '08 #12
On Nov 7, 11:54*am, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
Prateek <sure...@gmail.comwrites:
How about using (x, type(x)) as the key instead of just x?
Yup. I thought of that. Although it seems kinda unpythonic to do so.
Especially since the dictionary is basically a cache mostly containing
strings. Adding all the memory overhead for the extra tuples seems
like a waste just for those four keys.

You could use a second dict for the other type:

* def lookup(x):
* * if x in dict1: return dict1[x]
* * return dict2[x]

dict1 would have the 4 special keys and dict2 would have the regular
keys.

Ummm how do you get "the 4 special keys" in dict1?
E.g.
| >>dict(((0, '0'), (1, '1'), (False, 'f'), (True, 't')))
| {0: 'f', 1: 't'}
| >># Whoops!

Unless I'm missing something, the whole reason for the OP's problem is
that 0/False and 1/True are indistinguishable as dict keys (and set
members).

An alternative solution:
def lookup(x):
if x is False: return FALSE_VALUE
if x is True: return TRUE_VALUE
return normal_dict[x]

Cheers,
John
Nov 7 '08 #13
John Machin <sj******@lexicon.netwrites:
You could use a second dict for the other type:

* def lookup(x):
* * if x in dict1: return dict1[x]
* * return dict2[x]

dict1 would have the 4 special keys and dict2 would have the regular
keys.


Ummm how do you get "the 4 special keys" in dict1?
oops, adjoin the type

def lookup(x):
if (x,type(x)) in dict1: return dict1[x]
return dict2(x)

so dict1 would contain tuples as keys, but just a few of them.
Nov 7 '08 #14
On Nov 7, 3:05*pm, Paul Rubin <http://phr...@NOSPAM.invalidwrote:
John Machin <sjmac...@lexicon.netwrites:
You could use a second dict for the other type:
def lookup(x):
if x in dict1: return dict1[x]
return dict2[x]
dict1 would have the 4 special keys and dict2 would have the regular
keys.
Ummm how do you get "the 4 special keys" in dict1?

oops, adjoin the type

* * *def lookup(x):
* * * *if (x,type(x)) in dict1: return dict1[x]
Possibly you meant:

key = (x, type(x))
if key in dict1: return dict1[key]
* * * *return dict2(x)

so dict1 would contain tuples as keys, but just a few of them.
Nov 7 '08 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: none | last post by:
or is it just me? I am having a problem with using a dictionary as an attribute of a class. This happens in python 1.5.2 and 2.2.2 which I am accessing through pythonwin builds 150 and 148...
4
by: brianobush | last post by:
# # My problem is that I want to create a # class, but the variables aren't known # all at once. So, I use a dictionary to # store the values in temporarily. # Then when I have a complete set, I...
4
by: Bradley Plett | last post by:
I have what should be a trivial problem. I am using XMLSerializer to serialize an object. It serializes boolean values as "True" and "False". I then want to use an XSLT on this XML, and I want...
1
by: john wright | last post by:
I have a dictionary oject I created and I want to bind a listbox to it. I am including the code for the dictionary object. Here is the error I am getting: "System.Exception: Complex...
8
by: akameswaran | last post by:
I wrote up a quick little set of tests, I was acutally comparing ways of doing "case" behavior just to get some performance information. Now two of my test cases had almost identical results which...
8
by: Brian L. Troutwine | last post by:
I've got a problem that I can't seem to get my head around and hoped somebody might help me out a bit: I've got a dictionary, A, that is arbitarily large and may contains ints, None and more...
3
by: JamesB | last post by:
I have a config screen in my app that updates a dictionary<key,value>. I want to store a copy of this before going into the config screen so if the user wants to cancel all their changes I can...
3
by: wildThought | last post by:
If I have an object that contains a generic dictionary inside of it, how do I get access to its properties such as count?
1
by: sachin2 | last post by:
I am using 3 types of dictionaries. 1) Dictionary<string, string > d = new Dictionary<string, string>(); 2) Dictionary<string, List<string>> d = new Dictionary<string, List<string>>(); 3)...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
1
by: Aftab Ahmad | last post by:
So, I have written a code for a cmd called "Send WhatsApp Message" to open and send WhatsApp messaage. The code is given below. Dim IE As Object Set IE =...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: marcoviolo | last post by:
Dear all, I would like to implement on my worksheet an vlookup dynamic , that consider a change of pivot excel via win32com, from an external excel (without open it) and save the new file into a...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shllpp 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.