Try This
{unicodedata.normalize("NFKD", key): unicodedata.normalize("NFKD", item) for key, item in dict1.items()}
Output
'Repeat interval': '23 days',
'Epoch': '25 January 2015, 00:45:13 UTC[2]',
'Band': 'S Band(TT&C support)X Band(science data acquisition)',
'Bandwidth': 'up to 722kbit/s download (S Band)up to 18.4Mbit/s download (X Band)up to 4kbit /s upload (S Band)'}
Answer from WONDER on Stack OverflowHi! I was wondering if there's any way to replace characters in strings that are part of a dictionary? For example:
x = {"dog" : ["corgi", "Husky", "shiba"]} ----> x = {"Dog" : ["Corgi", "Husky", "Shiba"]}
In this example, I need to capitalize the first letter in each string if it's not capitalized already. I can't use any string methods and the only list method I can use is .insert(). I can use .chr() and .ord()
Try This
{unicodedata.normalize("NFKD", key): unicodedata.normalize("NFKD", item) for key, item in dict1.items()}
Output
'Repeat interval': '23 days',
'Epoch': '25 January 2015, 00:45:13 UTC[2]',
'Band': 'S Band(TT&C support)X Band(science data acquisition)',
'Bandwidth': 'up to 722kbit/s download (S Band)up to 18.4Mbit/s download (X Band)up to 4kbit /s upload (S Band)'}
You can try replace:
python 3.x
>>> dict2 = {k.replace(u'\xa0', ' ') : v.replace(u'\xa0', ' ') for k, v in dict1.items()}
or
python 2.7
>>> dict2 = {k.replace(u'\xa0', ' ') : v.replace(u'\xa0', ' ') for k, v in dict1.iteritems()}
The result is
>>> print(dict2)
{'Band': 'S Band(TT&C support)X Band(science data acquisition)',
'Bandwidth': 'up to 722kbit/s download (S Band)up to 18.4Mbit/s download (X Band)up to 4kbit /s upload (S Band)',
'Epoch': '25 January 2015, 00:45:13 UTC[2]',
'Period': '100.02 minutes[2]',
'Repeat interval': '23 days'}
python - String replacement using dictionaries - Code Review Stack Exchange
python - How to recursively replace character in keys of a nested dictionary? - Stack Overflow
python - Replace character in dict keys recursively - Stack Overflow
Python replacing characters in a dictionary of strings using a dictionary - Stack Overflow
Yes, there exists better way:
def print_dict(d):
new = {}
for k, v in d.iteritems():
if isinstance(v, dict):
v = print_dict(v)
new[k.replace('.', '-')] = v
return new
(Edit: It's recursion, more on Wikipedia.)
Actually all of the answers contain a mistake that may lead to wrong typing in the result.
I'd take the answer of @ngenain and improve it a bit below.
My solution will take care about the types derived from dict (OrderedDict, defaultdict, etc) and also about not only list, but set and tuple types.
I also do a simple type check in the beginning of the function for the most common types to reduce the comparisons count (may give a bit of speed in the large amounts of the data).
Works for Python 3. Replace obj.items() with obj.iteritems() for Py2.
def change_keys(obj, convert):
"""
Recursively goes through the dictionary obj and replaces keys with the convert function.
"""
if isinstance(obj, (str, int, float)):
return obj
if isinstance(obj, dict):
new = obj.__class__()
for k, v in obj.items():
new[convert(k)] = change_keys(v, convert)
elif isinstance(obj, (list, set, tuple)):
new = obj.__class__(change_keys(v, convert) for v in obj)
else:
return obj
return new
If I understand the needs right, most of users want to convert the keys to use them with mongoDB that does not allow dots in key names.
Hello,
I'm not sure if this is possible, but I have some data in the form of a dict. The problem is that sometimes both keys and values contains the \n character.
For example:
foo = {
"bar\n": "\n",
"foo\n": "elo",
"foobs": "\n",
...
}I would like to replace all of the \n characters with an empty string -> ""
I tried:
empty_dict = {}
for key, value in foo.items():
x = key.replace("\\n", "")
y = value.replace("\\n", "")
empty_dict[x] = y
print(empty_dict)
----------------------------------
{'bar\n': '\n', 'foo\n': 'elo', 'foobs': '\n'}
expected:
{'bar': '', 'foo': 'elo', 'foobs': ''}Is this possible to do?
Thank you!
Strings are immutable, you can't change a character by assignment. You can use replace, if you do e.g.
val = val.replace(...)
But to change only the last character you need:
val = val[:-1] + val[-1].replace(...)
Or just:
val = val[:-1] + "d"
However, this still won't update the dictionary, again because strings are immutable and this creates a new object. To do that:
d[key] = ...
As the error says, string can't be modified, since they are immutable (See http://effbot.org/pyfaq/why-are-python-strings-immutable.htm for example).
You need to do what you want, you can do the following:
if key[-1] == "d" and val[-1] == "t":
val = "%sd" % val[:-1] # Take the val, except the last character and add a "d"
print key, val
You can't use replace here, otherwise it will change every t in your string by d (even those at the beginning of the string)
You can write a recursive function, like this
from collections.abc import Mapping
def rec_key_replace(obj):
if isinstance(obj, Mapping):
return {key.replace('.', '_'): rec_key_replace(val) for key, val in obj.items()}
return obj
and when you invoke this with the dictionary you have shown in the question, you will get a new dictionary, with the dots in keys replaced with _s
{'delicious_apples': {'green_apples': 2}, 'green_pear': 4, 'brown_muffins': 5}
Explanation
Here, we just check if the current object is an instance of dict and if it is, then we iterate the dictionary, replace the key and call the function recursively. If it is actually not a dictionary, then return it as it is.
Assuming . is only present in keys and all the dictionary's contents are primitive literals, the really cheap way would be to use str() or repr(), do the replacement, then ast.literal_eval() to get it back:
d ={
"brown.muffins": 5,
"green.pear": 4,
"delicious_apples": {
"green.apples": 2
} # correct brace
}
Result:
>>> import ast
>>> ast.literal_eval(repr(d).replace('.','_'))
{'delicious_apples': {'green_apples': 2}, 'green_pear': 4, 'brown_muffins': 5}
If the dictionary has . outside of keys, we can replace more carefully by using a regular expression to look for strings like 'ke.y': and replace only those bits:
>>> import re
>>> ast.literal_eval(re.sub(r"'(.*?)':", lambda x: x.group(0).replace('.','_'), repr(d)))
{'delicious_apples': {'green_apples': 2}, 'green_pear': 4, 'brown_muffins': 5}
If your dictionary is very complex, with '.' in values and dictionary-like strings and so on, use a real recursive approach. Like I said at the start, though, this is the cheap way.
Have another dictionary with your replacements, like this
keys = {"a": "append", "h": "horse", "e": "exp", "s": "see"}
Now, if your events look like this
event_types = {"as": 0, "ah": 0, "es": 0, "eh": 0}
Simply reconstruct it with dictionary comprehension, like this
>>> {" ".join([keys[char] for char in k]): v for k, v in event_types.items()}
{'exp see': 0, 'exp horse': 0, 'append see': 0, 'append horse': 0}
Here, " ".join([keys[char] for char in k]), iterates the characters in the k, fetches corresponding words from keys dictionary and forms a list. Then, the elements of the list are joined with space character, to get the desired key.
Not sure if you can append or not, but you can do the following one liner:
>>> dict={}
>>> dict={"a":"b"}
>>> dict["aha"]=dict.pop("a")
>>> dict
{'aha': 'b'}
You can traverse the keys and change them according to your need.
address = "123 north anywhere street"
for word, initial in {"NORTH": "N", "SOUTH": "S"}.items():
address = address.replace(word.lower(), initial)
print(address)
nice and concise and readable too.
One option I don't think anyone has yet suggested is to build a regular expression containing all of the keys and then simply do one replace on the string:
>>> import re
>>> l = {'NORTH':'N','SOUTH':'S','EAST':'E','WEST':'W'}
>>> pattern = '|'.join(sorted(re.escape(k) for k in l))
>>> address = "123 north anywhere street"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address, flags=re.IGNORECASE)
'123 N anywhere street'
>>>
This has the advantage that the regular expression can ignore the case of the input string without modifying it.
If you want to operate only on complete words then you can do that too with a simple modification of the pattern:
>>> pattern = r'\b({})\b'.format('|'.join(sorted(re.escape(k) for k in l)))
>>> address2 = "123 north anywhere southstreet"
>>> re.sub(pattern, lambda m: l.get(m.group(0).upper()), address2, flags=re.IGNORECASE)
'123 N anywhere southstreet'
import datetime
ticketsearch= "2019-10-11T23:57:34Z"
response= datetime.datetime.strptime(f'{ticketsearch}', '%Y-%m-%dT%H:%M:%SZ')
new_Date = response .strftime('%Y-%m-%d %H:%M:%S')
I believe it can be achieved in many ways like:
1:
response = "2019-10-11T23:57:34Z"
response = response.replace('T', ' ')
response = response.replace('Z', '')
# output: 2019-10-11 23:57:34
2:
response = "2019-10-11T23:57:34Z"
avoidList = ['T', 'Z']
for char in response:
if char in avoidList:
response = (response.replace(char, ' ').strip())
# output: 2019-10-11 23:57:34