Understanding the use of d[key] = None

Learning some python by reading some code and trying to understand the usage of None on the dictionary's. Could you please bring some more light on the following snippet. and the usage of the = None .

for pc in csv_dict:
        if pc in shp_dict:
            matched[pc] = None
        else:
            csv_not_in_shp[pc] = None

Thanks


I think you're right to be confused, because this doesn't strike me as the finest example of Python coding. Just looking at the identifier names, we can sort of see the author's intent:

for pc in csv_dict:
    if pc in shp_dict:
        matched[pc] = None
    else:
        csv_not_in_shp[pc] = None

So here we have a csv_dict and shp_dict coming in, and we're writing out to two more dicts called matched or csv_not_in_shp . Clearly what this is setting up for later is a similar kind of test where the author can see:

if thing in matched:
    # it was in both csv_dict and shp_dict earlier
elif thing in csv_not_in_shp:
    # it wasn't so do something else

When you break it down like this, you can already start to see the problems. For instance, why do we need elif here? That could easily be rewritten:

if thing in matched:
    # it was in both csv_dict and shp_dict earlier
else:
    # it wasn't so do something else

This (probably correctly) suggests that csv_not_in_shp isn't necessary at all.

But let's give the original author the benefit of the doubt. Maybe csv_dict and shp_dict won't be around at the time of this comparison. (Pretty weak reason since they could have been passed from presumably the same place matched and csv_not_in_shp were, but...) The real problem here is that the author is using None for the value because he doesn't care what the value is . In other words, he's very much using it as a NULL placeholder.

The problem is, this is because he's not mapping a key to a value . The author is overlooking a clear use case for sets . Observe:

matched = set()
for pc in csv_dict:
    if pc in shp_dict:
        matched.add(pc)

Now we are saying what we really mean. Here's a basic example illustrating the concept. Let d be a dict mapping the letters 'a' to 'e' to the numbers 0 through 4, and d_ be a dict mapping 'd' to 'g' to the numbers 3 through 6. (I will use OrderedDicts below so the keys are presented in a more readable format. They are otherwise unnecessary.)

>>> import string
>>> from collections import OrderedDict as od
>>> d = od([(k,v) for k, v in zip(string.ascii_lowercase[:5], range(5))])
>>> d_ = od([(k,v) for k, v in zip(string.ascii_lowercase[3:7], range(3,7))])
>>> d
OrderedDict([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4)])
>>> d_
OrderedDict([('d', 3), ('e', 4), ('f', 5), ('g', 6)])
>>> matched = set()
>>> for key in d:
...   if key in d_:
...     matched.add(key)
... 
>>> matched
{'e', 'd'}

With a set, we can still do in matching, which is all we wanted in the first place:

>>> 'a' in matched
False
>>> 'd' in matched
True 

And the best thing, of course, is that the whole thing can be reduced down to a set comprehension:

>>> {key for key in d if key in d_}
{'e', 'd'}

So matched = {pc for pc in csv_dict if pc in shp_dict} would more correctly replace your original code with a set, following my example.


None is similar to null (with subtle differences) in other programming languages. In this case, it is being used to indicate that the key pc does not currently have a value. Therefore, when you try to access it, instead of giving you a KeyError, it will simply return None .

None can also be used in if statements to check for existence:

>>> a = None
>>> b = 5

>>> if a:
...     print 'a Exists'
>>> if b:
...     print 'b Exists'
...
b Exists

In this case above, the if statement checks to see whether a value exists and is not None .

Something closer to your example:

>>> a = [None,None,1,2.234,'d',None]
>>> for i,item in enumerate(a):
...     if item:
...         print i, item
...
2 1
3 2.234
4 d

Here is a Useful Reference

链接地址: http://www.djcxy.com/p/76636.html

上一篇: 执行计数,排序/映射大型字典

下一篇: 了解使用d [key] =无