Use Dict Comprehension to modify Values that contain lists - python

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.

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

How do I save changes made in a dictionary values to itself?

I have a dictionary where the values are a list of tuples.
dictionary = {1:[('hello, how are you'),('how is the weather'),('okay
then')], 2:[('is this okay'),('maybe It is')]}
I want to make the values a single string for each key. So I made a function which does the job, but I do not know how to get insert it back to the original dictionary.
my function:
def list_of_tuples_to_string(dictionary):
for tup in dictionary.values():
k = [''.join(i) for i in tup] #joining list of tuples to make a list of strings
l = [''.join(k)] #joining list of strings to make a string
for j in l:
ki = j.lower() #converting string to lower case
return ki
output i want:
dictionary = {1:'hello, how are you how is the weather okay then', 2:'is this okay maybe it is'}
You can simply overwrite the values for each key in the dictionary:
for key, value in dictionary.items():
dictionary[key] = ' '.join(value)
Note the space in the join statement, which joins each string in the list with a space.
It can be done even simpler than you think, just using comprehension dicts
>>> dictionary = {1:[('hello, how are you'),('how is the weather'),('okay then')],
2:[('is this okay'),('maybe It is')]}
>>> dictionary = {key:' '.join(val).lower() for key, val in dictionary.items()}
>>> print(dictionary)
{1: 'hello, how are you how is the weather okay then', 2: 'is this okay maybe It is'}
Now, let's go through the method
we loop through the keys and values in the dictionary with dict.items()
assign the key as itself together with the value as a string consisting of each element in the list.
The elemts are joined together with a single space and set to lowercase.
Try:
for i in dictionary.keys():
dictionary[i]=' '.join(updt_key.lower() for updt_key in dictionary[i])

Dict comprehension from split str

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(';')}

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)

if-else comprehension with dictionary not working in python3

dlist=['All my loving','All my bros','And all sis']
I would like to create a dictionary such that all words (as keys) are assigned a value which is index of dlist in which the words appear.
For example,
'All':{0,1}, 'my':{0,1},'sis'={2} etc.
Somehow this does not work:
dict={}
{w:{num} if w not in dict.keys() else dict[w].add(num) for (num,strn) in enumerate(dlist) for w in strn.split()}
This returns
{'All':{2}, 'my':{2}}
Looks like else statement is being ignored. Any pointers?
Thanks
This doesn't work because you are trying to access dict.keys while you are creating dict in a dict comprehension. If this was in a for loop, dict.keys would be updated each element, but the dict comprehensions ensures that the dict is not updated mid-creation to improve speed.
Something like this should work:
myDict = {}
for (num, strn) in enumerate(dlist):
for w in strn.split():
if w not in myDict:
myDict[w] = {num}
else:
myDict[w].add(num)

Categories

Resources