Python "valueless" dictionary [duplicate] - python

This question already has answers here:
Is there a Python dict without values?
(3 answers)
Closed 2 years ago.
I have a problem where I want to keep track over a large number of values. If I never encountered the value, I'll do action A, otherwise - action B. Naturally, I considered using dictionary to keep track of the values, since the lookup is fast, ~O(1).
However, dictionary is a key-value system, while all I want to take advantage of, is the key.
I can assign a bogus value
"myvalue": None
but I can't help but wonder if there's a more elegant way to go about it.
Thoughts? Ideas?
Thanks!

That's what a set is for:
members = set()
members.add("mykey")
members.add("otherkey")
if "mykey" in members:
. . .

If I were to stick to your dict implementation, I would:
if value in dict:
#Action B
else:
#Action A
dict[value] = 1
so that you wouldn't need to save unseen values in your dict in the first place.

The best suited for your task is frozenset().
The frozenset type is immutable and hashable — its contents cannot be
altered after it is created; it can therefore be used as a dictionary
key or as an element of another set.
members = frozenset([keylist])
if "mykey" in members:
Based on your question, this is the best suited collection form for your task in python.

Related

What is the community preferred Python design pattern for accumulating values in a dictionary? [duplicate]

This question already has answers here:
How to count the frequency of the elements in an unordered list? [duplicate]
(33 answers)
Closed 3 years ago.
I often find myself writing this pattern for accumulating counts about a thing in a dictionary.
In this case, I'm gathering up host hardware information for a datacenter application, and the pattern is the same I have often used.
Today, I was wondering if there is a better way (more Pythonic) to construct this pattern?
I did take a look around S.O. the most common result is using append on a list to add things which do not exist, but that does not address how to do an accumulator in a dictionary where the incoming key/value may or may not exist in the dictionary already.
hardware_types = []
for host in hosts:
hardware_type = hosts[host]['hardware_type']
if hardware_type in hardware_types:
hardware_types[hardware_type] += 1
else:
hardware_types[hardware_type] = 1
Thanks,
Bob
I often use defaultdict for this kind of scenario. On declaration you specify what the default value is and it will be generated when you refer to it the first time. In this case you'd want a 0, and can use the int type as a constructor:
from collections import defaultdict
hardware_types = defaultdict(int)
for host in hosts:
hardware_type = hosts[host]['hardware_type'])
hardware_types[hardware_type] += 1
It can be nested, include dictionaries via lambdas, etc.
It helps keep code a bit lighter by avoiding checking if the key exists, however be careful with assumptions as in case the key should exist but does not due to a bug, it will be created and won't raise an exception.

Dictionary value is different in input and different in output [duplicate]

This question already has answers here:
How to keep keys/values in same order as declared?
(13 answers)
Closed 4 years ago.
I have some error in Python 3 while using dictionaries. The input and output does not match
What you are getting is not an error. Read about dictionaries first: https://www.w3schools.com/python/python_dictionaries.asp
Dictionaries don't work as list. They do not have order. They are hashed data structure that strongly binds keys with value. 5 will always be bound with "five" and 4 will always be bound with "four". If you type dict1[5], you will always get 'five'. In dictionaries, order of arrangement is not important, because python uses complex algorithms to keep key - value bound by hashing, and these algorithms may alter the order of arrangement, but order of arrangement is anyways not important for us in dictionaries.
Never use dictionaries as lists. Dictionaries are collection of key value pairs and you access a value by a key. Lists are like arrays, you access a value by index.

How are Python dictionaries (builtin hashtables) implemented? [duplicate]

This question already has answers here:
How are Python's Built In Dictionaries Implemented?
(3 answers)
Closed 8 years ago.
I was wondering how is the python dict (dictionary/hashtable) implemented. Particularly, if I write something like
my_dict = {"key": {"key: {"key": "value"}}}
what possibly does the python interpreter do? I want to know the internal working of it.
Does it treat each dictionary as an object (mostly yes)? If so, is the hashing same for same keys across different dictionaries? For e.g.
dict1 = {"key": "value", "k": "v"}
dict2 = {"key": [1, 2.], "k": "value"}
How different would the look-up for the keys in these 2 distinct dicts be? Also, how does it decide the size of the buckets? Or is similar to the handling of list size?
Hope you get my question. Thanks!
EDIT - No, I am not asking how hash-tables work. I know that part.
Python dictionary are basically the implementation of hash tables. Now, the question is what is hash table? From wikipedia, short and sweet answer:
a hash table (also hash map) is a data structure used to implement an
associative array, a structure that can map keys to values
A hash table uses a hash function to compute an index into an array of buckets or slots, from which the correct value can be found.
These two questions in SO covers some of the things you are interested in:
How are Python's Built In Dictionaries Implemented
How can Python dict have multiple keys with same hash?
I would be repeating the same things if I go any further.
The specification reads
Another useful data type built into Python is the dictionary (see
Mapping Types — dict). Dictionaries are sometimes found in other
languages as “associative memories” or “associative arrays”.
It is best to think of a dictionary as an unordered set of key: value
pairs, with the requirement that the keys are unique (within one
dictionary). A pair of braces creates an empty dictionary: {}. Placing
a comma-separated list of key:value pairs within the braces adds
initial key:value pairs to the dictionary; this is also the way
dictionaries are written on output.
And places items in memory in a deterministic fashion through a hash function

Is there a better way to store a twoway dictionary than storing its inverse separate? [duplicate]

This question already has answers here:
How to implement an efficient bidirectional hash table?
(8 answers)
Closed 9 years ago.
Given a one-to-one dictionary (=bijection) generated à la
for key, value in someGenerator:
myDict[key] = value
an inverse lookup dictionary can be trivially created by adding
invDict[value] = key
to the for loop. But is this a Pythonic way? Should I instead write a class Bijection(dict) which manages this inverted dictionary in addition and provides a second lookup function? Or does such a structure (or a similar one) already exist?
What I've done in the past is created a reversedict function, which would take a dict and return the opposite mapping, either values to keys if I knew it was one-to-one (throwing exceptions on seeing the same value twice), or values to lists of keys if it wasn't. That way, instead of having to construct two dicts at the same time each time I wanted the inverse look-up, I could create my dicts as normal and just call the generic reversedict function at the end.
However, it seems that the bidict solution that Jon mentioned in the comments is probably the better one. (My reversedict function seems to be his bidict's ~ operator).
if you want O(log(n)) time for accessing values, you will need both a representation of the map and a representation of the inverse map.
otherwise the best you can do is O(log(n)) in one direction and O(n) in the other.
Edit: not O(log(n)), thanks Claudiu, but you are still going to need two data structures to implement the quick access times. And this will be more or less the same space as a dict and an inverse dict.

Turn dict into list wipes out the values [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Short question: Why when we do list(dict()) the return is the keys of the dict, but not the values?
Cause all that I know about (key, value) pairs, is that what matters is the value, not the key. The key it's just a page in a book. Since we don't actually want the page, but the content of that page, giving me the page makes no sense at all at first.
I believe that it, somehow, makes sense. But please, clarify this one.
Thanks!
EDITED:
now, since the most relevant part of a (key, value) pair ITS THE VALUE. Why not the the iter method of dict returns the value?
It is simply untrue that the value is "the most relevant part" of the key-value pair. The pair itself is what is relevant. That's why you're using a dict. If all you wanted was the values, you'd just use a list.
Also, as #Blender rightly points out, if you know the key, you can easily get the value, whereas the reverse is not true. So if you're only going to get one, it definitely makes sense to get the key and not the value.
Although it's true that in and iteration behavior are not necessarily linked, it's also true that for most other container types, iterating over the container yields all and only the items for which item in container would be true. I seem to recall seeing threads on comp.lang.python at one point where people said that the decision to make in on dictionaries work by key, and to make iteration work like in, was made a long time ago and then maintained for backwards compatibility, although I can't find any references for that right now.
It is legitimate to wonder why iterating overa dict yields the keys and not the key/value pairs. But the answer to this is just "that's the way the dict API specifies it". Iterating over the key-value pairs (or the values alone, if it comes to that) is so trivially easy, with a single method call, that it hardly matters which one is the default behavior.
The reason why this occurs is because list accepts an iterator, and uses each item as if it was an iterator by calling iter on it. Since the __iter__ method of the dict type returns an iterator over it's keys, calling list on a dict object gives you it's keys.
>>> class A(object):
def __init__(self,lst):
self.lst = lst
def __iter__(self):
print 'iter on A'
return iter(self.lst)
>>> a = A(range(10))
>>> list(a)
iter on A
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In terms of implementation, returning only keys would be the faster than returning both, and since they explicitly include an items method, there doesn't exist a very good reason for including values in the default __iter__ implementation. Implementation of DICT The TimeComplexity data from python indicate that iterating over keys is O(n) and retrieving values is O(1), which may seem insignificant, until you realize that iterating and retrieving values given keys is O(n) also. This would be wasteful unless you really wanted the key,value pairs (as opposed to just keys, or just values), so it's not the default.
If you wanted it to be the default, you could do this:
class myDict(dict):
def __iter__(self):
return self.iteritems()
and calling list on an instance of myDict will give you key, value pairs.
Why when we do list(dict()) the return is the keys of the dict, but
not the values?
First, doing dict() will not return any keys or values, but an empty dictionary. You are calling the built-in dict function.
If you type exactly that in the shell, you'll end up with an empty list [].
By the way, you also can't do:
d = {'a': 1, 'b': 2}
list(d())
This will raise a TypeError since dictionary objects are not callable.
By default if you loop over a dictionary, due to its implementation, the default iterator will return keys. This is the straight forward answer to your question. The reason for this implementation is that in Python, there is only one type that you can use to retrieve values by using any hashable type, and that is a dictionary. Hence, the primary use case for this type would be to retrieve items by their key, which can be any arbitrary value. In addition, since dictionaries are unordered getting easy access to the keys is the easiest way and I would argue the primary reason to even use a dictionary. Otherwise, what's wrong with a list? or tuple?
If you have a dictionary and you want to convert it to a list, you need to somehow 'flatten' the dictionary. This is because lists already have a 0-indexed key, which I am sure you already know.
To get list(somedict) to create a list of the values of any dictionary, you have a few ways.
The first one which was hinted in the comments; and is the most straightforward way:
list({'a': 1, 'b': 2}.values())
If you want to add some syntactic sugar on it, but this is just being silly:
d = {'a': 1, 'b': 2}.values
list(d())
Finally, if you want to have both the keys and the values in your list, you can do this:
list({'a': 1, 'b': 2}.values())
[('a', 1),('b', 2)]
Now you have a list of tuples, each representing a key/value pair. Some developers use this to sort the dictionary as dictionaries are unsorted in Python. In Python 2.7, OrderedDict was added to the collections module, which provides sorted dictionaries.

Categories