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. 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?
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
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.
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
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
"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
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
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
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
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
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.
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
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.
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.
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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...
|
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?
|
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)...
|
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...
|
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 =...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
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...
|
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...
|
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)...
|
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...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
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....
| |