Dict comprehension from split str - python

I'm trying to make a dict out this str:
a='ALLELEID=677660;CLNDISDB=MedGen:C0162671,OMIM:540000,Orphanet:ORPHA550,SNOMED_CT:39925003;CLNDN=Juvenile_myopathy,_encephalopathy,_lactic_acidosis_AND_stroke;CLNHGVS=NC_012920.1:m.15992A>T;CLNREVSTAT=criteria_provided,_single_submitter;CLNSIG=Likely_benign;CLNVC=single_nucleotide_variant;CLNVCSO=SO:0001483;GENEINFO=MT-TP:4571;ORIGIN=1'
This works:
d={}
for i in a.split(';'):
key, val = i.split('=')
d[key] = val
Why doesn't this work?
d={key: val for key, val in i.split('=') for i in a.split(';')}

You cannot have nested dictionary comprehensions (unlike nested list comprehensions). The following will work:
dict(item.split("=") for item in a.split(';'))
dict() can build a dictionary from a list of 2-element lists or tuples.

Try using:
d={i.split('=')[0]: i.split('=')[1] for i in a.split(';')}
The second loop isn't needed (even if you needed it it would be wrong, you would need to put the second loop after the first loop).

To use list comprehensions here you should use:
{key: val for i in a.split(';'), for key, val in i.split('=')}
But even you changed your code to this, it won't work since this is wrong:
for key, val in i.split('=')
the results of i.split('=') is an 1d array where you can only iterate with one element.
So eventually, you will only need one level of list comprehension:
{i.split('=')[0]: i.split('=')[1] for i in a.split(';')}

Related

tuple to list conversion within dictionary values (list of lists (and tuples))

I am dealing with a dictionary that is formatted as such:
dic = {'Start': [['Story' , '.']],
'Wonderful': [('thing1',), ["thing1", "and", "thing2"]],
'Amazing': [["The", "thing", "action", "the", "thing"]],
'Fantastic': [['loved'], ['ate'], ['messaged']],
'Example': [['bus'], ['car'], ['truck'], ['pickup']]}
if you notice, in the story key, there is a tuple within a list. I am looking for a way to convert all tuples within the inner lists of each key into lists.
I have tried the following:
for value in dic.values():
for inner in value:
inner = list(inner)
but that does not work and I don't see why. I also tried an if type(inner) = tuple statement to try and convert it only if its a tuple but that is not working either... Any help would be very greatly appreciated.
edit: I am not allowed to import, and only have really learned a basic level of python. A solution that I could understand with that in mind is preferred.
You need to invest some time learning how assignment in Python works.
inner = list(inner) constructs a list (right hand side), then binds the name inner to that new list and then... you do nothing with it.
Fixing your code:
for k, vs in dic.items():
dic[k] = [list(x) if isinstance(x, tuple) else x for x in vs]
You need to update the element by its index
for curr in dic.values():
for i, v in enumerate(curr):
if isinstance(v, tuple):
curr[i] = list(v)
print(dic)
Your title, data and code suggest that you only have tuples and lists there and are willing to run list() on all of them, so here's a short way to convert them all to lists and assign them back into the outer lists (which is what you were missing) (Try it online!):
for value in dic.values():
value[:] = map(list, value)
And a fun way (Try it online!):
for value in dic.values():
for i, [*value[i]] in enumerate(value):
pass

Use Dict Comprehension to modify Values that contain lists

How might I refactor this loop into a Dict Comprehension? Should I?
for key,val in myDict.items():
if '[' in val:
myDict[key] = (ast.literal_eval(val))
For context, some of the values in the dictionary are lists, but formatted as strings; they come from an excel file. Anytime '[' is encountered in a cell, I want the dictionary value to be the literal cell value, not a string of it.
Do you want something like this?
{key: ast.literal_eval(val) if '[' in val else val for key, val in myDict.items()}
In my opinion, for this case List Comprehension is less understandable than classic loop.

Cannot convert a dictionary into list of tuples and sort it

I want to find outliers keys (names) in my dataset, so that I am trying to create a list of tuples from my dictionary and sort them by salary. That is my code
for key, value in data_dict.iteritems():
sorted_dict_list = []
sorted_dict_list.append((key, value["salary"], value["bonus"]))
sorted_dict_list.sort(key=lambda tup: tup[1])
for tuple in sorted_dict_list:
print tuple
The problem is that the printed output is unsorted. What might be the problem?
You should declare sorted_dict_list outside the first for loop, otherwise each time you go through the loop you have a new empty list. On top of that, your loop through sorted_dict_list is inside the first for loop.
So each time you loop through the outer loop you create an empty list, add the next key-value pair into it, run through the list (which is only one item long) and print out the values. Basically you are just printing out each key-value pair as you go through.
You need to move the list declaration outside the loop and un-indent the second loop.
sorted_dict_list = []
for key, value in data_dict.iteritems():
sorted_dict_list.append((key, value["salary"], value["bonus"]))
sorted_dict_list.sort(key=lambda tup: tup[1])
for tuple in sorted_dict_list:
print tuple
This might be a better solution:
def sortKey(item):
return item[1]
sorted_dict = [(key, value['salary'], value['bonus']) for key, value in data_dict.items()]
sorted_dict = sorted(sorted_dict, key=sortKey)
for item in sorted_dict:
print(item)

Can't seem to iterate over a sorted dictionary where the keys are number strings. How do you sort a dictionary to iterate?

I have this dictionary (dic) where the keys are strings, but the strings are actually just numbers.
I can't find a way to iterate over the sorted string (since sorting the dictionary will not sort numerically)
for j in sorted([int(k) for k in dic.iteritems()]):
print dic[str(j)] #converting the integer back into a string for the key
it gives me
KeyError
Intuitively this should work, but I just dont get why it doesn't.
dict.iteritems() returns 2-tuples, which cannot be converted into ints.
for j in sorted(dic, key=int):
print dic[j]
Apart from using key=int you could also slightly modify your existing comprehension:
for _, value in sorted((int(key), dic[key]) for key in dic):
print(value)
it's not as nice but it's an alternative if you want to unpack not only your keys but also your values.
With iteritems you need an additional unpacking in the comprehension:
for _, value in sorted((int(key), value) for key, value in dic.iteritems()):
print(value)

How to access dictionary elements in a list in python

I'm trying to understand about dictionaries and list in Python.
Assume that I have a list which contains 3 dictionaries
Ex. item_list = [price,stock,quantity]
price, stock and quantity are the dictionaries here. Each dictionary has few key-value pairs like
price = {'toys':25,'clothes':[12,15,20]}
I know to access individual elements, I can use a for loop with the keys specified like:
for item in item_list:
print item['toys']
How do I access the elements without directly mentioning the key in the for loop?
You can iterate over a dictionary just like you can iterate over a list.
for item in item_list:
for key in item:
print item[key]
In a sense, you're still mentioning the keys, but you're not referencing them explicitly by their value.
If you're just interested in the values you can use the values() method:
for item in item_list:
for key in item.values():
print item[key]
My preferred way to iterate over dictionaries though is with items, which returns a tuple of key, value pairs.
for item in item_list:
for key, value in item.items():
print key, value
I would do something like this:
for item in item_list:
for key, value in item.iteritems():
print key, value
Let us say, you have a list like this
prices_list = [{'toys':25,'clothes':[12,15,20]},{'toys':35,'clothes':[12,15,20]}]
And you would like to get the value corresponding to toys, but without specifying the name in the for loop. So, you can use operator.itemgetter like this
from operator import itemgetter
getter = itemgetter("toys")
print [getter(item) for item in prices_list]
# [25, 35]
The same can be used like this
total = 0
for item in prices_list:
total += getter(item)
for d in item_list:
for i in d.values():
print i
You could also call d.items() and get back tuples of (key, value) if you wanted access to both.
Additionally if you don't care about readability you could use this to get a list of all the values accross the dicts in your list.
[x for y in (i.values() for i in item_list) for x in y]
You can also use: [d for i in item_list for d in i.values()] to get the values and flatten them into a list (though yours would still be nested because of clothes' value being a list.
Finally you can merge the dictionaries into one if they have distinct keys:
joint_mapping = dict([d for i in item_list for d in i.items()])
or if they don't have unique values you can use the below code to produce a dict of lists of values. :
for k, v in [d for i in item_list for d in i.items()]:
new_d[k] = new_d.get(k, [])+[v]
You mentioned :
#Eenvincible - I would be inputting those values to other variable.
Print is just an example I gave. So would not want to hardcode the key.
I think you can do your trick using for loop as mentioned in other answers.
for item in item_list:
for key in item:
print item[key]
tempvariable = item[key]
.... do something here.
If you want to assign each value to a seperate variable, you should:
- First, assign that variables to any insignificant value EX: **None** or *""*
- Then, dynamically use the for loop to reassign each variable to new value using if condition or thier index.
EX:
price_toys , price_clothes , stock_toys , stock_clothes = None , None , None , None
for item in item_list:
for key in item:
tempvariable = item[key]
# condition to choose which varible will be set to the current value.
if item == "price" and key == "toys":
price_toys = tempvariable
# and so on

Categories

Resources