I am trying to solve this problem: I have some symbols:
list =["RBS-UK", "GOOG-US"]
Now I have to transform all the region occurrences of "UK" to "GB". I could have done this easily:
new_list =[]
for symbol in list :
temp_list=symbol.split("-")
if temp_list[1]=="UK":
temp_list[1]="GB"
new_list.append("-".join(temp_list))
But can I do this without the equality comparision?
I am looking for something along the lines of:
some_dict={}
new_list =[]
for symbol in list :
temp_list=symbol.split("-")
temp_list[1]=some_dict(temp_list[1]) # So this dict returns GB if its UK else returns same value as it is
new_list.append("-".join(temp_list))
Is it possible to do this, or are there any other solutions?
Yeah! sure
ls =['RBS-UK','GOOG-US']
map(lambda x: x.replace('-UK', '-GB'), ls)
You are looking for a lookup, for which a dictionary will work:
translations = {'UK':'GB'} # and so on
for symbol in lst:
country_code = symbol.split('-')[1]
translated = translations.get(country_code,country_code)
new_list.append('{}-{}'.format(symbol.split('-')[0],translated))
The key line is:
translated = translations.get(country_code,country_code)
Dictionary have a method get() which will return None if the key is not found. We use this to avoid raising KeyError. get() takes an optional second parameter for a value to return other than None if the key is not found.
In the snippet above, we pass the country code to get(), and ask it to return the same country code if there isn't a translation available, otherwise return the translation.
The second line uses string formatting to reconstruct the original symbol with the translated code and appends it to your list.
You don't actually have to redefine the offset. You can simply replace the string:
for symbol in list:
symbol = symbol.replace('-UK','-GB')
If the string is encountered it will be replaced, otherwise it is left alone entirely.
If you really want to use a dict, you could use the dict.get method, which accepts a default argument used when the key isn't found, and so some_dict.get(x,x) means "return the value associated with x if it exists, otherwise return x":
>>> some_dict = {"UK": "GB"}
>>> country = "UK"
>>> some_dict.get(country, country)
'GB'
>>> country = "CA"
>>> some_dict.get(country, country)
'CA'
You can use the sub function from the re module useful for regular expression operations.
Here is a one-liner which produces the list you want:
import re
newlist = [re.sub('UK','GB', symbol) for symbol in list]
Related
I would like to optimize this piece of code. I'm sure there is a way to write it in a single line:
if 'value' in dictionary:
x = paas_server['support']
else:
x = []
use dictionary get() method as:
x = dictionary.get('support', [])
if support is not a key in the dictionary, it returns second method's argument, here, an empty list.
I have a dataframe which contains the below column:
column_name
CUVITRU 8 gram
CUVITRU 1 grams
I want to replace these gram and grams to gm. So I have created a dictionary
dict_ = {'gram':'gm','grams':'gm'}
I am able to replace it but it is converting grams to gms. Below is the column after conversion:
column_name
CUVITRU 8 gm
CUVITRU 1 gms
How can I solve this issue.
Below is my code:
dict_ = {'gram':'gm','grams':'gm'}
for key, value in dict_abbr.items():
my_string = my_string.replace(key,value)
my_string = ' '.join(unique_list(my_string.split()))
def unique_list(l):
ulist = []
[ulist.append(x) for x in l if x not in ulist]
return ulist
because it finds 'gram' in 'grams', one way is to instead of string use reg exp for replacement on word boundaries, like (r"\b%s\.... look at the answer usign .sub here for example: search-and-replace-with-whole-word-only-option
You don't actually care about the dict; you care about the key/value pairs produced by its items() method, so just store that in the first place. This lets you specify the order of replacements to try regardless of your Python version.
d = [('grams':'gm'), ('gram':'gm')]
for key, value in d:
my_string = my_string.replace(key,value)
You can make replacements in the reverse order of the key lengths instead:
dict_ = {'gram':'gm','grams':'gm'}
for key in sorted(dict_abbr, key=len, reverse=True):
my_string = my_string.replace(key, dict_[key])
Put the longer string grams before the shorter one gram like this {'grams':'gm','gram':'gm'}, and it will work.
Well, I’m using a recent python 3 like 3.7.2 which guarantees that the sequence of retrieving items is the same as that they are created in the dictionary. For earlier Pythons that may happen (and this appears to be the problem) but isn’t guaranteed.
I got a nested dictionary as follows and it will return the third key while inputting the first key in the dictionary
tree = {"Luke" : {"Darth Vader" : {"The Chancellor"}},
"Neal" : {"Les" : {"Joseph"}},
"George" : {"Fred" : {"Mickey"}},
"Robert" : {"Tim" : {"Michael"}},
"Juan" : {"Hunter" : {"Thompson"}}}
check_con = input("Enter your Name")
for fi_name,fi_second in tree.items():
if check_con in fi_name:
for fi_third,fi_fourth in fi_second.items():
print(fi_fourth)
I feel that its bit more steps, is there any other way to do it?
Regard
You can use dict.get method with a default value of empty dict to get the top level dict and then convert its values to a iter, use next to get the first value
>>> check_con = 'Neal'
>>> next(iter(tree.get(check_con, {}).values()), '')
{'Joseph'}
>>>
>>> check_con = 'xxx'
>>> next(iter(tree.get(check_con, {}).values()), '')
''
>>>
You can simply use a try-excep expression in order to find out whether your name exist in the dictionary or not. If it exist there you can then return all the values of the respective value:
def get_nested_item(tree, check_on):
try:
sub_dict = tree[check_on]
except KeyError:
print("No result")
return
else:
return sub_dict.values()
Also note that about checking the existence of your name in dictionary what you're ding here is a membership checking at following line:
if check_con in fi_name:
Which will not check for equality but checks if check_con appears within the dictionary keys. However if this is what you want you have to loop over your items and find the intended one. But also note that this may have multiple answers or in other words there may be multiple keys matching your criteria which contradicts with the whole purpose of using a dictionary.
Demo:
In [11]: get_nested_item(tree, "George")
Out[11]: dict_values([{'Mickey'}])
In [12]: get_nested_item(tree, "Luke")
Out[12]: dict_values([{'The Chancellor'}])
In [13]: get_nested_item(tree, "Sarah")
No result
this is a variant where i use next(iter(...)) in order to get the 'first' element of your dict and set (note that you innermost curly brackets in your tree are sets and not dicts):
def get(tree, name):
def first(seq):
return next(iter(seq))
if name in tree:
return first(first(tree[name].values()))
else:
return None
print(get(tree=tree, name='Juan')) # 'Thompson'
print(get(tree=tree, name='Jan')) # None
as both sets and dict_values (which is the type dict(...).values() returns) are not indexable (have no __getitem__ method) i turn them into an iterator using iter and get the first element using next.
def endcode(msg,secret_d):
for ch in msg:
for key,value in secret_d:
if ch == key:
msg[ch] = value
return msg
encode('CAN YOU READ THIS',{'A':'4','E':'3','T':'7','I':'1','S':'5'})
This is my code. What I am trying to do here is for every characters in a string msg, the function should search in the dictionary and replace it with the mapping string if the character ch is a key in the dictionary secret_d.
If ch is not a key in secret_d than keep it unchanged.
For the example, the final result is should be 'C4N YOU R34D 7H15'
Your function name is endcode but you are calling encode.
But more important, I'll give you a hint to what's going on. This isn't going to totally work, but it's going to get you back on track.
def endcode(msg,secret_d):
newstr=""
for ch in msg:
for key,value in secret_d.iteritems():
if ch == key:
newstr=newstr+value
print(msg)
endcode('CAN YOU READ THIS',{'A':'4','E':'3','T':'7','I':'1','S':'5'})
But if you want a complete answer, here is mine.
A few issues:
As rb612 pointed out, there's a typo in your function definition ("endcode")
you are doing nothing with the return value of your function after calling it
msg[ch] is trying to assign items in a string, but that's not possible, strings are immutable. You'll have to build a new string. You cannot "update" it.
in order to iterate over (key, value) pairs of a dictionary d, you must iterate over d.items(). Iterating over d will iterate over the keys only.
That being said, here's my suggestion how to write this:
>>> def encode(msg, replacers):
... return ''.join([replacers.get(c, c) for c in msg])
...
>>> result = encode('CAN YOU READ THIS',{'A':'4','E':'3','T':'7','I':'1','S':'5'})
>>> result
'C4N YOU R34D 7H15'
Things to note:
dict.get can be called with a fallback value as the second argument. I'm telling it to just return the current character if it cannot be found within the dictionary.
I'm using a list comprehension as the argument for str.join instead of a generator expression for performance reasons, here's an excellent explanation.
I am writing code in python.
My input line is "all/DT remaining/VBG all/NNS of/IN "
I want to create a dictionary with one key and multiple values
For example - all:[DT,NNS]
groupPairsByKey={}
Code:
for line in fileIn:
lineLength=len(line)
words=line[0:lineLength-1].split(' ')
for word in words:
wordPair=word.split('/')
if wordPair[0] in groupPairsByKey:
groupPairsByKey[wordPair[0]].append(wordPair[1])
<getting error here>
else:
groupPairsByKey[wordPair[0]] = [wordPair[1]]
Your problem is that groupPairsByKey[wordPair[0]] is not a list, but a string!
Before appending value to groupPairsByKey['all'], you need to make the value a list.
Your solution is already correct, it works perfectly in my case. Try to make sure that groupPairsByKey is a completely empty dictionary.
By the way, this is what i tried:
>>> words = "all/DT remaining/VBG all/NNS of/IN".split
>>> for word in words:
wordPair = word.split('/')
if wordPair[0] in groupPairsByKey:
groupPairsByKey[wordPair[0]].append(wordPair[1])
else:
groupPairsByKey[wordPair[0]] = [wordPair[1]]
>>> groupPairsByKey
{'of': ['IN'], 'remaining': ['VBG'], 'all': ['DT', 'NNS']}
>>>
Also, if your code is formatted like the one you posted here, you'll get an indentationError.
Hope this helps!
Although it looks to me like you should be getting an IndentationError, if you are getting the message
str object has no attribute append
then it means
groupPairsByKey[wordPair[0]]
is a str, and strs do not have an append method.
The code you posted does not show how
groupPairsByKey[wordPair[0]]
could have a str value. Perhaps put
if wordPair[0] in groupPairsByKey:
if isinstance(groupPairsByKey[wordPair[0]], basestring):
print('{}: {}'.format(*wordPair))
raise Hell
into your code to help track down the culprit.
You could also simplify your code by using a collections.defaultdict:
import collections
groupPairsByKey = collections.defaultdict(list)
for line in fileIn:
lineLength=len(line)
words=line[0:lineLength-1].split(' ')
for word in words:
wordPair=word.split('/')
groupPairsByKey[wordPair[0]].append(wordPair[1])
When you access a defaultdict with a missing key, the factory function -- in this case list -- is called and the returned value is used as the associated value in the defaultdict. Thus, a new key-value pair is automatically inserted into the defaultdict whenever it encounters a missing key. Since the default value is always a list, you won't run into the error
str object has no attribute append anymore -- unless you have
code which reassigns an old key-value pair to have a new value which is a str.
You can do:
my_dict["all"] = my_string.split('/')
in Python,