I have a nested dictionary where the lowest level consists of a list with one element each. I want to change this level from list to string.
Assume I have a dictionary such as this:
dict = {id1:{'key11':['value11'],'key12':['value12']}, id2:{'key21':['value21'],'key22':['value22']}}
How can I get:
dict = {id1:{'key11': 'value11','key12':'value12'}, id2:{'key21':'value21','key22':'value22'}}
Additional question:
How does the solution change if the keys and values do not follow a certain logic but each element is unique and you have many of them; such as in the below example:
dictionary = {'ida':{'abc':['def'],'fgh':['ijk'] (...)}, 'idb':{'lmn':['opq'],'rst':['uvw']} (...)}
Thank you!!
Note:
I get this structure because I am using a list/map structure earlier in the code to extract text from a XML file which yields list values.
get_text = lambda x: x.text
content = [list(map(get_text, i)) for i in content]
This works:
dictionary = {'id1':{'key11':['value11'],'key12':['value12']}, 'id2':{'key21':['value21'],'key22':['value22']}}
new_dict = {key: {key1:value1[0] for key1, value1 in value.items()} for key, value in dictionary.items()}
new_dict
#{'id1': {'key11': 'value11', 'key12': 'value12'},
# 'id2': {'key21': 'value21', 'key22': 'value22'}}
Also, I would not use predefined terms like dict
I have a list like this-
send_recv_pairs = [(['produce_send'], ['consume_recv']), (['Send'], ['Recv']), (['sender2'], ['receiver2'])]
I want something like
[ {['produce_send']:['consume_recv']},{['Send']:['Recv']},{['sender2']:['receiver2']}
How to do this?
You can not use list as the key of dictionary.
This Article explain the concept,
https://wiki.python.org/moin/DictionaryKeys
To be used as a dictionary key, an object must support the hash function (e.g. through hash), equality comparison (e.g. through eq or cmp), and must satisfy the correctness condition above.
And
lists do not provide a valid hash method.
>>> d = {['a']: 1}
TypeError: unhashable type: 'list'
If you want to specifically differentiate the key values you can use tuple as they hash able
{ (i[0][0], ): (i[1][0], ) for i in send_recv_pairs}
{('Send',): ('Recv',),
('produce_send',): ('consume_recv',),
('sender2',): ('receiver2',)}
You can't have lists as keys, only hashable types - strings, numbers, None and such.
If you still want to use a dictionary knowing that, then:
d={}
for tup in send_recv_pairs:
d[tup[0][0]]=tup[1]
If you want the value to be string as well, use tup[1][0] instead of tup[1]
As a one liner:
d={tup[0][0]]:tup[1] for tup in list} #tup[1][0] if you want values as strings
You can check it over here, in the second way of creating distionary.
https://developmentality.wordpress.com/2012/03/30/three-ways-of-creating-dictionaries-in-python/
A Simple way of doing it,
First of all, your tuple is tuple of lists, so better change it to tuple of strings (It makes more sense I guess)
Anyway simple way of working with your current tuple list can be like :
mydict = {}
for i in send_recv_pairs:
print i
mydict[i[0][0]]= i[1][0]
As others pointed out, you cannot use list as key to dictionary. So the term i[0][0] first takes the first element from the tuple - which is a list- and then the first element of list, which is the only element anyway for you.
Do you mean like this?
send_recv_pairs = [(['produce_send'], ['consume_recv']),
(['Send'], ['Recv']),
(['sender2'], ['receiver2'])]
send_recv_dict = {e[0][0]: e[1][0] for e in send_recv_pairs}
Resulting in...
>>> {'produce_send': 'consume_recv', 'Send': 'Recv', 'sender2': 'receiver2'}
As mentioned in other answers, you cannot use a list as a dictionary key as it is not hashable (see links in other answers).
You can therefore just use the values in your lists (assuming they stay as simple as in your example) to create the following two possibilities:
send_recv_pairs = [(['produce_send'], ['consume_recv']), (['Send'], ['Recv']), (['sender2'], ['receiver2'])]
result1 = {}
for t in send_recv_pairs:
result1[t[0][0]] = t[1]
# without any lists
result2 = {}
for t in send_recv_pairs:
result2[t[0][0]] = t[1][0]
Which respectively gives:
>>> result1
{'produce_send': ['consume_recv'], 'Send': ['Recv'], 'sender2': ['receiver2']}
>>> result2
{'produce_send': 'consume_recv', 'Send': 'Recv', 'sender2': 'receiver2'}
Try like this:
res = { x[0]: x[1] for x in pairs } # or x[0][0]: x[1][0] if you wanna store inner values without list-wrapper
It's for Python 3 and when keys are unique. If you need collect list of values per key, instead of single value, than you may use something like itertools.groupby or map+reduce. Wrote about this in comments and I'll provide example.
And yes, list cannot store key-values, only dict's, but maybe it's just typo in question.
You can not use list as the dictionary key, but instead you may type-cast it as tuple to create the dict object.
Below is the sample example using a dictionary comprehension:
>>> send_recv_pairs = [(['produce_send'], ['consume_recv']), (['Send'], ['Recv']), (['sender2'], ['receiver2'])]
>>> {tuple(k): v for k, v in send_recv_pairs}
{('sender2',): ['receiver2'], ('produce_send',): ['consume_recv'], ('Send',): ['Recv']}
For details, take a look at: Why can't I use a list as a dict key in python?
However if your nested tuple pairs were not list, but any other hashable object pairs, you may have type-casted it to dict for getting the desired result. For example:
>>> my_list = [('key1', 'value1'), ('key2', 'value2')]
>>> dict(my_list)
{'key1': 'value1', 'key2': 'value2'}
This is what my dictionary looks like.
phoneBook = {"Skywalker": 55511243, "Solo": 55568711, "Vader": 55590858}
I need to change each phonenumber into a string and add "+1-" in front of it. But, I'm not sure how to do it.
With a simple dictionary comprehension:
r = {k: "+1-{}".format(v) for k,v in phoneBook.items()}
Where "+1-{}".format(v) converts to a string and prepends +1- to it. Similarly you could use "+1-" + str(v) as noted in the other answer but I personally find it less readable.
print(r)
{'Skywalker': '+1-55511243', 'Solo': '+1-55568711', 'Vader': '+1-55590858'}
Alternatively, if you want to do it in-place, i.e not create a new dictionary as comprehensions do, iterate over the keys* and update the values:
for k in phoneBook:
phoneBook[k] = "+1-{}".format(phoneBook[k])
*Iterating over the keys only is important, if you iterate over both keys and values you'll get odd behavior because you'll be altering the view you iterate through.
Use a dictionary comprehension
{k:'+1-'+str(phoneBook[k]) for k in phoneBook}
I have a defaultdict(list) dictionary and im trying to access the stored values to perform some operations on them only i've never had to do this before so im not quite sure how to access them givin a list index and a key.
listdict = defaultdict(list)
listdict = {'Cake':['cheesecake','icecream cake','oreo-cheesecake']}
so e.g. say i wanted to use "Cake" key word to access "oreo-cheesecake" string at index 2 in the list.
You are overwriting your defaultdict. It mostly works as a normal dict. We set elements:
listdict = defaultdict(list)
listdict['Cake'] = ['cheesecake','icecream cake','oreo-cheesecake']
And we recover them:
print listdict['Cake'][2]
'oreo-cheesecake'
But you can do:
listdict['nonexistent'].append('stuff')
I am currently working with a dataframe consisting of a column of 13 letter strings ('13mer') paired with ID codes ('Accession') as such:
However, I would like to create a dictionary in which the Accession codes are the keys with values being the 13mers associated with the accession so that it looks as follows:
{'JO2176': ['IGY....', 'QLG...', 'ESS...', ...],
'CYO21709': ['IGY...', 'TVL...',.............],
...}
Which I've accomplished using this code:
Accession_13mers = {}
for group in grouped:
Accession_13mers[group[0]] = []
for item in group[1].iteritems():
Accession_13mers[group[0]].append(item[1])
However, now I would like to go back through and iterate through the keys for each Accession code and run a function I've defined as find_match_position(reference_sequence, 13mer) which finds the 13mer in in a reference sequence and returns its position. I would then like to append the position as a value for the 13mer which will be the key.
If anyone has any ideas for how I can expedite this process that would be extremely helpful.
Thanks,
Justin
I would suggest creating a new dictionary, whose values are another dictionary. Essentially a nested dictionary.
position_nmers = {}
for key in H1_Access_13mers:
position_nmers[key] = {} # replicate key, val in new dictionary, as a dictionary
for value in H1_Access_13mers[key]:
position_nmers[key][value] = # do something
To introspect the dictionary and make sure it's okay:
print position_nmers
You can iterate over the groupby more cleanly by unpacking:
d = {}
for key, s in df.groupby('Accession')['13mer']:
d[key] = list(s)
This also makes it much clearer where you should put your function!
... However, I think that it might be better suited to an enumerate:
d2 = {}
for pos, val in enumerate(df['13mer']):
d2[val] = pos