convert python list into dictionary with key only , no value - python

I have a list of room names in python, however I need it to be a dictionary, simply in the form {"room1", "room2", "room3"}
Currently, my code can take the list and turn to a dictionary with both values and keys, i.e. {"room1":0, "room2":1, "room3": 2} etc.
my code is as follows:
rooms = ["G5a", "G5b", "G11"]
roomdict = dict(zip(rooms,range(len(rooms))))
print(roomdict)
But, this is not the format I need my dictionary to be in - thanks for your help in advanace :)

What you need is a set:
A set is an unordered collection of items. Every element is unique (no duplicates) and must be immutable (which cannot be changed).
rooms = ["G5a", "G5b", "G11"]
print(set(rooms))
OUTPUT:
{'G5b', 'G5a', 'G11'}

On the odd chance that your really need a dict with keys and empty values:
mydict = {"room1" : None, "room2": None, "room3" : None}
You could use the dict.fromkeys() method:
rooms = ["G5a", "G5b", "G11"]
roomdict = dict.fromkeys(rooms, None)
print(roomdict)
Output:
{'G5b': None, 'G11': None, 'G5a': None}

Related

clearing a dictionary but keeping the keys

Is it possible to clear all the entries within a dictionary but keep all the keys?
For example if I had:
my_dic={
"colour":[],
"number":[]
}
I put some stuff in them:
my_dic["colour"]='Red'
my_dic["number"]='2'
I can clear these by:
my_dic["colour"] = []
my_dic["number"] = []
But this is long winded if I want to clear a large dictionary quickly, is there a quicker way perhaps using for? I want to keep the keys ["colour"], ["number"], without having to recreate them, just clear all the entries within them.
You can simply clear all lists in a loop:
for value in my_dic.values():
del value[:]
Note the value[:] slice deletion; we are removing all indices in the list, not the value reference itself.
Note that if you are using Python 2 you probably want to use my_dic.itervalues() instead of my_dic.values() to avoid creating a new list object for the loop.
Demo:
>>> my_dic = {'colour': ['foo', 'bar'], 'number': [42, 81]}
>>> for value in my_dic.values():
... del value[:]
...
>>> my_dic
{'colour': [], 'number': []}
You could also replace all values with new empty lists:
my_dic.update((key, []) for key in my_dic)
or replace the whole dictionary entirely:
my_dic = {key: [] for key in my_dic}
Take into account these two approaches will not update other references to either the lists (first approach) or the whole dictionary (second approach).
You no need to delete keys from dictionary:
for key in my_dict:
my_dict[key] = []
One liner:
my_dict = dict.fromkeys(my_dict, None)
You can also replace the None type with other values that are immutable. A mutable type such as a list will cause all of the values in your new dictionary to be the same list.
For mutable types you would have to populate the dictionary with distinct instances of that type as others have shown.

Checking items in a list of dictionaries in python

I have a list of dictionaries=
a = [{"ID":1, "VALUE":2},{"ID":2, "VALUE":2},{"ID":3, "VALUE":4},...]
"ID" is a unique identifier for each dictionary. Considering the list is huge, what is the fastest way of checking if a dictionary with a certain "ID" is in the list, and if not append to it? And then update its "VALUE" ("VALUE" will be updated if the dict is already in list, otherwise a certain value will be written)
You'd not use a list. Use a dictionary instead, mapping ids to nested dictionaries:
a = {
1: {'VALUE': 2, 'foo': 'bar'},
42: {'VALUE': 45, 'spam': 'eggs'},
}
Note that you don't need to include the ID key in the nested dictionary; doing so would be redundant.
Now you can simply look up if a key exists:
if someid in a:
a[someid]['VALUE'] = newvalue
I did make the assumption that your ID keys are not necessarily sequential numbers. I also made the assumption you need to store other information besides VALUE; otherwise just a flat dictionary mapping ID to VALUE values would suffice.
A dictionary lets you look up values by key in O(1) time (constant time independent of the size of the dictionary). Lists let you look up elements in constant time too, but only if you know the index.
If you don't and have to scan through the list, you have a O(N) operation, where N is the number of elements. You need to look at each and every dictionary in your list to see if it matches ID, and if ID is not present, that means you have to search from start to finish. A dictionary will still tell you in O(1) time that the key is not there.
If you can, convert to a dictionary as the other answers suggest, but in case you you have reason* to not change the data structure storing your items, here's what you can do:
items = [{"ID":1, "VALUE":2}, {"ID":2, "VALUE":2}, {"ID":3, "VALUE":4}]
def set_value_by_id(id, value):
# Try to find the item, if it exists
for item in items:
if item["ID"] == id:
break
# Make and append the item if it doesn't exist
else: # Here, `else` means "if the loop terminated not via break"
item = {"ID": id}
items.append(id)
# In either case, set the value
item["VALUE"] = value
* Some valid reasons I can think of include preserving the order of items and allowing duplicate items with the same id. For ways to make dictionaries work with those requirements, you might want to take a look at OrderedDict and this answer about duplicate keys.
Convert your list into a dict and then checking for values is much more efficient.
d = dict((item['ID'], item['VALUE']) for item in a)
for new_key, new_value in new_items:
if new_key not in d:
d[new_key] = new_value
Also need to update on key found:
d = dict((item['ID'], item['VALUE']) for item in a)
for new_key, new_value in new_items:
d.setdefault(new_key, 0)
d[new_key] = new_value
Answering the question you asked, without changing the datastructure around, there's no real faster way of looking without a loop and checking every element and doing a dictionary lookup for each one - but you can push the loop down to the Python runtime instead of using Python's for loop.
I haven't tried if it ends up faster though.
a = [{"ID":1, "VALUE":2},{"ID":2, "VALUE":2},{"ID":3, "VALUE":4}]
id = 2
tmp = filter(lambda d: d['ID']==id, a)
# the filter will either return an empty list, or a list of one item.
if not tmp:
tmp = {"ID":id, "VALUE":"default"}
a.append(tmp)
else:
tmp = tmp[0]
# tmp is bound to the found/new dictionary

Initializing a dictionary in python with a key value and no corresponding values

I was wondering if there was a way to initialize a dictionary in python with keys but no corresponding values until I set them. Such as:
Definition = {'apple': , 'ball': }
and then later i can set them:
Definition[key] = something
I only want to initialize keys but I don't know the corresponding values until I have to set them later. Basically I know what keys I want to add the values as they are found. Thanks.
Use the fromkeys function to initialize a dictionary with any default value. In your case, you will initialize with None since you don't have a default value in mind.
empty_dict = dict.fromkeys(['apple','ball'])
this will initialize empty_dict as:
empty_dict = {'apple': None, 'ball': None}
As an alternative, if you wanted to initialize the dictionary with some default value other than None, you can do:
default_value = 'xyz'
nonempty_dict = dict.fromkeys(['apple','ball'],default_value)
You could initialize them to None.
you could use a defaultdict. It will let you set dictionary values without worrying if the key already exists. If you access a key that has not been initialized yet it will return a value you specify (in the below example it will return None)
from collections import defaultdict
your_dict = defaultdict(lambda : None)
It would be good to know what your purpose is, why you want to initialize the keys in the first place. I am not sure you need to do that at all.
1) If you want to count the number of occurrences of keys, you can just do:
Definition = {}
# ...
Definition[key] = Definition.get(key, 0) + 1
2) If you want to get None (or some other value) later for keys that you did not encounter, again you can just use the get() method:
Definition.get(key) # returns None if key not stored
Definition.get(key, default_other_than_none)
3) For all other purposes, you can just use a list of the expected keys, and check if the keys found later match those.
For example, if you only want to store values for those keys:
expected_keys = ['apple', 'banana']
# ...
if key_found in expected_keys:
Definition[key_found] = value
Or if you want to make sure all expected keys were found:
assert(all(key in Definition for key in expected_keys))
You can initialize the values as empty strings and fill them in later as they are found.
dictionary = {'one':'','two':''}
dictionary['one']=1
dictionary['two']=2
Comprehension could be also convenient in this case:
# from a list
keys = ["k1", "k2"]
d = {k:None for k in keys}
# or from another dict
d1 = {"k1" : 1, "k2" : 2}
d2 = {k:None for k in d1.keys()}
d2
# {'k1': None, 'k2': None}
q = input("Apple")
w = input("Ball")
Definition = {'apple': q, 'ball': w}
Based on the clarifying comment by #user2989027, I think a good solution is the following:
definition = ['apple', 'ball']
data = {'orange':1, 'pear':2, 'apple':3, 'ball':4}
my_data = {}
for k in definition:
try:
my_data[k]=data[k]
except KeyError:
pass
print my_data
I tried not to do anything fancy here. I setup my data and an empty dictionary. I then loop through a list of strings that represent potential keys in my data dictionary. I copy each value from data to my_data, but consider the case where data may not have the key that I want.

Python: can I modify a Tuple?

I have a 2 D tuple (Actually I thought, it was a list.. but the error says its a tuple)
But anyways..
The tuple is of form:
(floatnumber_val, prod_id)
now I have a dictionary which contains key-> prod_id and value prod_name
now.. i want to change the prod_id in tuple to prod_name
So this is waht I did
#if prodName is the tuple
# prodDict is the dictionary
for i in range(len(prodName)):
key = prodName[i][1] # get the prodid
if prodDict.has_key(key):
value = prodDict[key]
prodName[i][1] = value
umm pretty straightforward
but i get an error that TypeError: 'tuple' object does not support item assignment
Thanks!!
Tuples are not mutable, you cannot change them.
The thing to do is probably to find out why you are creating tuples instead of the list you expected.
If prodName is a list of tuples and you want to create a new list of tuples like you explained, you have to create new tuples since a tuple is immutable (i.e. it can not be changed).
Example:
for i,(floatnumber_val, prod_id) in enumerate(prodName):
prodName[i] = (floatnumber_val, prodDict.get(prod_id,prod_id))
Short answer: you cannot.
Tuples are immutable. Lists are mutable. That's really the key distinction.
If you want to mutate an ordered collection of items in Python it's going to have to be a list. If you want to stick to tuples you're going to have to make a new one. If I've understood you correctly you are starting with:
prodName = [(1.0, 1), (1.1, 2), (1.2, 3)]
prodDict = {1: 'name_1', 2: 'name_2', 3: 'name_3'}
So, you can get the list you want with:
new_prodName = [(f, prodDict[id]) for f, id in prodName)]
This will fail if the id isn't found in the prodDict dict. If you want it to fail early that's great. If not, you can set a default (ex: None) using .get():
new_prodName = [(f, prodDict.get(id, None)) for f, id in prodName)]
Unfortunately, you can't modify the tuple. Use lists instead.
prodName[i] = tuple(prodName[i][0], value)

Python: How to access data from this type of list?

Quick Python question: How do I access data from a nested list like this:
{'album': [u'Rumours'], 'comment': [u'Track 3'], 'artist': [u'Fleetwood Mac'], 'title': [u'Never Going Back Again'], 'date': [u'1977'], 'genre': [u'Rock'], 'tracknumber': [u'03']}
I tried listname[0][0] but it returns the error:
AttributeError: 'int' object has no attribute 'lower'
So how would I go about doing this?
This is not a list, it is a dictionary. It takes an immutable type as key and any type as value for every key,value pair. In your case this is a dictionary with str type keys and list's as values. You must first extract the list from the dictionary, and then the first element from the list, assuming you meant that:
somedict = {"test": [u"spam"], "foo": [u"bar"]}
print(somedict["test"][0])
Please note that a dictionary is not type-bound and can mix types:
somedict = {1: "test", "foo": ["bar", "spam"]}
And some more information about dictionaries can be found here: http://docs.python.org/tutorial/datastructures.html#dictionaries
This is not a list. This is a dictionary.
The dictionary is not ordered, and thus it cannot be accessed through a numeric index*.
You must refer to to it like this: listname['album']
The above will return you a list with one element (which happens to be a list): [u'Rumours'], to acces a list, you do as usual.
So altogether:
listname['album'][0]
# Will output the string inside the list.
Notice that the list could have more elements, so you would refer them like so [0],[1] etc.
Take a look at the docs for more information.
*You can do:
d = {2:"a",1:"b"}
print d[1] ### prints string b
What I meant is that you don't use zero based indexes, you use keys that can be "whatever you want" and this keys refer to values.

Categories