Read a string in dictionary values and replace a specific character - python

I have a dict in which each value is a string. In some values, this string has "-" that I would like to remove. I have been told that it is not possible to replace the values of a dict. Is that right?
mydict
'GCA_000010565.1_genomic Ribosomal_L10:': '-TRAEKEAIIQELKEKFKEARVAVLADYRGLNV-------AEATRLRRRLREAGCEFKVAKNTLTGLAARQAGLE-----GLDPYLEGPIAIAFG-VDPVAPAKVLSDF--',
I would wish something like
mydict
'GCA_000010565.1_genomic Ribosomal_L10:': 'TRAEKEAIIQELKEKFKEARVAVLADYRGLNVAEATRLRRRLREAGCEFKVAKNTLTGLAARQAGLEGLDPYLEGPIAIAFGVDPVAPAKVLSDF',

Absolutly you can, just iterate over the mappings key/value, and change the associated value by the processed one
d = {'superkey': "foo--bar", 'superkey2': "--foo--bar",
'GCA_000010565.1_genomic Ribosomal_L10:': '-TRAEKEAIIQELKEKFKEARVAVLADYRGLNV-------AEATRLRRRLREAGCEFKVAKNTLTGLAARQAGLE-----GLDPYLEGPIAIAFG-VDPVAPAKVLSDF--', }
# LOOP version
for k, v in d.items():
d[k] = v.replace("-", "")
# DICT COMPREHENSION version
d = {k: v.replace("-", "") for k, v in d.items()}
print(d) # {'superkey': 'foobar', 'superkey2': 'foobar',
'GCA_000010565.1_genomic Ribosomal_L10:': 'TRAEKEAIIQELKEKFKEARVAVLADYRGLNVAEATRLRRRLREAGCEFKVAKNTLTGLAARQAGLEGLDPYLEGPIAIAFGVDPVAPAKVLSDF'}

Yes it is possible. You can simply use
mydict['GCA_000010565.1_genomic Ribosomal_L10:'] = mydict['GCA_000010565.1_genomic Ribosomal_L10:'].replace("-","")

No, you've been told BS. The solution:
for k in mydict:
mydict[k] = mydict[k].replace('-', '')

Related

Drop keys from a dictionary based on a string value in Python

Why doesn't this work:
I have a dictionary inside dictionary
{'rrr-rrr/CCC-3/FFFF-1': {'ActiveSet': '0'},
'rrr-rrr/CCC-4/FFFF-1': {'ActiveSet': '1'},
...}
And I need to drop keys where CCC is 3 (CCC-3).
The way I've tried is this:
my_dict = {k: v
for k, v in my_dict.iteritems()
if k.split('/')[1].split('-')[1]!= 3
}
And there is no error with this code, but nothing happens. I've tried also to make new key inside inner dict from that CCC number but that doesn't work too.
Desired output:
{'rrr-rrr/CCC-4/FFFF-1': {'ActiveSet': '1'},
...}
As Jon Clements mentioned, you're comparing a string to an integer, so your if condition will never evaluate to true.
As a fix, I'd go with something more like:
val = 3
my_dict = {k : v
for k, v in my_dict.iteritems()
if 'CCC-{}'.format(val) not in k
}
This way, you don't have to hardcode your split and indexing. Note that, if you have keys of the form CCC-<number> where the number is two or more digits, you'll need to match CCC-{}/, as Danil Speransky smartly observes in his answer.
Note that the python 3 equivalent of dict.iteritems is dict.items.
Your code doesn't work because you compare an integer and a string. Change it to '3':
if k.split('/')[1].split('-')[1] != '3'
Or simpler:
if 'CCC-3/' not in k
I have added / to not exclude CCC-32.
You can just search for your desired pattern in the key:
new_data = {a:b for a, b in d.items() if "CCC-3" not in a}

How to split list inside a dictionnary to create a new one?

I've been struggling on something for the day,
I have a dictionnary under the format
dict = {a:[element1, element2, element3], b:[element4, element5, element6]...}
I want a new dictionnary under the form
newdict = {a:element1, b:element4...}
Meaning only keeping the first element of the lists contained for each value.
You can use a dictionary comprehension:
{k: v[0] for k, v in d.items()}
# {'a': 'element1', 'b': 'element4'}
Hopefully this helps.
I like to check if the dictionary has a key before overwriting a keys value.
dict = {a:[element1, element2, element3], b:[element4, element5, element6]}
Python 2
newDict = {}
for k, v in dict.iteritems():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]
Python 3
newDict = {}
for k, v in dict.items():
if k not in newDict:
# add the first list value to the newDict's key
newDick[k] = v[0]

How to convert a dict to string?

Assume I have a dict:
{
'a':'vala',
'b':'valb',
'c':'valc'
}
I want to convert this to a string:
"a='vala' , b='valb' c='valc'"
What is the best way to get there? I want to do something like:
mystring = ""
for key in testdict:
mystring += "{}='{}'".format(key, testdict[key]).join(',')
You can use str.join with a generator expression for this. Note that a dictionary doesn't have any order, so the items will be arbitrarily ordered:
>>> dct = {'a':'vala', 'b':'valb'}
>>> ','.join('{}={!r}'.format(k, v) for k, v in dct.items())
"a='vala',b='valb'"
If you want quotes around the values regardless of their type then replace {!r} with '{}'. An example showing the difference:
>>> dct = {'a': 1, 'b': '2'}
>>> ','.join('{}={!r}'.format(k, v) for k, v in dct.items())
"a=1,b='2'"
>>> ','.join("{}='{}'".format(k, v) for k, v in dct.items())
"a='1',b='2'"
Close! .join is used to join together items in an iterable by a character, so you needed to append those items to a list, then join them together by a comma at the end like so:
testdict ={
'a':'vala',
'b':'valb'
}
mystring = []
for key in testdict:
mystring.append("{}='{}'".format(key, testdict[key]))
print ','.join(mystring)
Well, just if you want to have a sorted result:
d={'a':'vala', 'b':'valb', 'c':'valc'}
st = ", ".join("{}='{}'".format(k, v) for k, v in sorted(d.items()))
print(st)
Result
a='vala', b='valb', c='valc'
" , ".join( "%s='%s'"%(key,val) for key,val in mydict.items() )

Python : Match a dictionary value with another dictionary key

I have two dictionaries created this way :
tr = defaultdict(list)
tr = { 'critic' : '2_critic',
'major' : '3_major',
'all' : ['2_critic','3_major']
}
And the second one :
scnd_dict = defaultdict(list)
And contains values like this :
scnd_dict = {'severity': ['all']}
I want to have a third dict that will contain the key of scnd_dict and its corresponding value from tr.
This way, I will have :
third_dict = {'severity' : ['2_critic','3_major']}
I tried this, but it didn't work :
for (k,v) in scnd_dict.iteritems() :
if v in tr:
third_dict[k].append(tr[v])
Any help would be appreciated. Thanks.
Well...
from collections import defaultdict
tr = {'critic' : '2_critic',
'major' : '3_major',
'all' : ['2_critic','3_major']}
scnd_dict = {'severity': ['all']}
third_dict = {}
for k, v in scnd_dict.iteritems():
vals = []
if isinstance(v, list):
for i in v:
vals.append(tr.get(i))
else:
vals.append(tr.get(v))
if not vals:
continue
third_dict[k] = vals
print third_dict
Results:
>>>
{'severity': [['2_critic', '3_major']]}
Will do what you want. But I question the logic of using defaultdicts here, or of have your index part of a list...
If you use non-lists for scnd_dict then you can do the whole thing much easier. Assuming scnd_dict looks like this: scnd_dict = {'severity': 'all'}:
d = dict((k, tr.get(v)) for k, v in scnd_dict.items())
# {'severity': ['2_critic', '3_major']}
Your problem is that v is a list, not an item of a list. So, the if v in tr: will be false. Change your code so that you iterate over the items in v
third_dict = {k: [t for m in ks for t in tr[m]] for k,ks in scnd_dict.iteritems()}
The second dict's value is list, not str, so the code blow will work
for (k, v) in send_dict.iteritems():
if v[0] in tr.keys():
third_dict[k] = tr[v[0]]
The problem is that the third dictionary does not knows that the values is a list
for k in scnd_dict:
for v in scnd_dict[k]:
print v
for k2 in tr:
if v==k2:
if k not in third_dict:
third_dict[k]=tr[k2]
else:
third_dict[k]+=tr[k2]
third_dict = {k: tr[v[0]] for k, v in scnd_dict.iteritems() if v[0] in tr}
This
tr = defaultdict(list)
is a waste of time if you are just rebinding tr on the next line. Likewise for scnd_dict.
It's a better idea to make all the values of tr lists - even if they only have one item. It will mean less special cases to worry about later on.

Python dictionary: Remove all the keys that begins with s

I've got a dictionary like
dic = {'s_good': 23, 's_bad': 39, 'good_s': 34}
I want to remove all the keys that begins with 's_'
So in this case first two will be removed.
Is there any efficient way to do so?
This should do it:
for k in dic.keys():
if k.startswith('s_'):
dic.pop(k)
for k in dic.keys():
if k.startswith('s_'):
del dic[k]
* EDIT *
now in python 3 , years after the original answer, keys() returns a view into the dict so you can't change the dict size.
One of the most elegant solutions is a copy of the keys:
for k in list(dic.keys()):
if k.startswith('s_'):
del dic[k]
With python 3 to avoid the error:
RuntimeError: dictionary changed size during iteration
This should do it:
list_keys = list(dic.keys())
for k in list_keys:
if k.startswith('s_'):
dic.pop(k)
You can use a dictionary comprehension:
dic = {k: v for k, v in dic.items() if not k.startswith("s_")}
Note that this creates a new dictionary (which you then assign back to the dic variable) rather than mutating the existing dictionary.
How about something like this:
dic = dict( [(x,y) for x,y in dic.items() if not x.startswith('s_')] )

Categories