This question already has answers here:
How can I use a dictionary to do multiple search-and-replace operations? [duplicate]
(13 answers)
Closed 3 years ago.
How to change the string to result?
string = 'John and Mary are good friends'
d = {'John': 'Sam', 'Mary': 'Ann', 'are': 'are not'}
result = 'Sam and Ann are not good friends'
Thank you.
If keys in dictionary have only one word is possible split, map by get and join back:
a = ' '.join(d.get(x, x) for x in string.split())
print (a)
Sam and Ann are not good friends
If possible multiple words and also is necessary use words boundaries for avoid replace substrings:
import re
string = 'John and Mary are good friends'
d = {'John and': 'Sam with', 'Mary': 'Ann', 'are good': 'are not'}
pat = '|'.join(r"\b{}\b".format(x) for x in d.keys())
a = re.sub(pat, lambda x: d.get(x.group(0)), string)
print (a)
Sam with Ann are not friends
You can do it like this:
string = 'John and Mary are good friends'
d = {'John': 'Sam', 'Mary': 'Ann', 'are': 'are not'}
result = string
for key, value in d.items():
result = result.replace(key, value)
print(result)
output:
Sam and Ann are not good friends
1 - Iterate over each word of string.
2 - check if word exists in dictionary keys.
3 - If it does exist append value of that word to result. if it does not, append word to result.
Basic approach:
split the long string into a list of words
iterate through this list of words; if any word exists as a key in the given dictionary, replace that word with the corresponding value from the dictionary
join the list of words together using space
string = 'John and Mary are good friends'
d = {'John': 'Sam', 'Mary': 'Ann', 'are': 'are not'}
s = string.split()
for i, el in enumerate(s):
if el in d:
s[i] = d[el]
print(' '.join(s))
Related
If I this list:
list1 = ['a long way home she said', 'amazing grace for me', 'shes super cool']
I want to compare each item in list 1 to the values in dict1 below:
dict1 = {
'Formula1': ('a long way home', 'nothing to see here'),
'Formula 2': ('nasty girl', 'nope'),
'Formula 3': ('disguisting', 'nope'),
'Formula 4': ('amazing grace', 'hello world')
}
How can I get the output to return the key from dict1 with the entire matching phrase in list1?
The desired output would be:
['Formula1': ('a long way home she said'), 'Formula 4': ('amazing grace for me')] or
{'Formula1': ('a long way home she said'), 'Formula 4': ('amazing grace for me')}
I was trying to do this like so:
import itertools
[x if not x in itertools.chain(dict1.values()) else [key for key in dict1 if value in dict[key]][0] for x in list1]
But I think my output is actually just going to return everything in the list after iterating through dictionary values. I have millions of records to go through so list comprehension is preferable to a loop.
[name for name, title in dict1.items() if all(x in title for x in list1)]
This just returned an empty list
For each key in the dictionary, create a new tuple. For every element in list1, if there exists a string in the original tuple value that is a substring of that element, then retain it in the result. Store the result of this computation (in the below code snippet, we store it in the phrases variable).
Then, we filter out all of the key-value pairs that have empty tuples for values using a dictionary comprehension. You could condense this into one line, but I think it becomes pretty unreadable at that point:
phrases = {
key: tuple(
filter(lambda x: any(substr in x for substr in value), list1)
)
for key, value in dict1.items()
}
result = {key: value for key, value in phrases.items() if value != ()}
print(result)
This outputs:
{
'Formula1': ('a long way home she said',),
'Formula 4': ('amazing grace for me',)
}
I need to sort the highscores of my game in order from highest to lowest but I also want the name next to it so it is still a string.
This is my list
highscores = ["Herbert 99999", "Bob 543", "Jerry 35", "Fred 325", "Tom 972"]
How do I sort these in order so I can print them out.
If you want the high score at the start of your list then:
highscores = ["Herbert 99999", "Bob 543", "Jerry 35", "Fred 325", "Tom 972"]
highscores.sort(key=lambda x: int(x.split()[-1]), reverse=True)
print(highscores)
Output:
['Herbert 99999', 'Tom 972', 'Bob 543', 'Fred 325', 'Jerry 35']
I think you would be a lot better off using a dictionary
highscores = {"Herbert": 99999, "Bob": 534, "Jerry":35}
Then you could just sort the dictionary by the values
dict(sorted(highscores.items(), key =lambda highscore: highscore[1], reverse=True))
Using a dictionary would also probably make your code more efficient.
I hope this helps, apologies if it doesn't!
highscores = ["Herbert 99999", "Bob 543", "Jerry 35", "Fred 325", "Tom 972"]
# temporary list of ordered pairs
tmp = sorted(map(str.split, highscores), key=lambda pair: int(pair[1]), reverse=True)
# marge each pair to get a list of strings
ordered_highscores = list(map(' '.join, tmp))
print(ordered_highscores)
Output
['Herbert 99999', 'Tom 972', 'Bob 543', 'Fred 325', 'Jerry 35']
highscores.sort(key=lambda x:int(x.split()[-1]))
gives
['Jerry 35', 'Fred 325', 'Bob 543', 'Tom 972', 'Herbert 99999']
Quite neat
You can use a key function that, for each string, returns a tuple of the form (score_as_integer, name_as_string). That way, ties will be sorted by name.
def by_score(item):
name, score = item.rsplit(maxsplit=1)
return -int(score), name.lower()
highscores.sort(key=by_score)
I have an input list of strings that are split by a comma like so:
list_to_split = ['flyer, black and white', 'flyer, blue', 'fly-swatter, black', 'helmet, heavy',
'armlet, silver and gold', 'cherry, black', 'violin, very old', 'concrete, grey']
I'd like to iterate over items starting with the same letters and update an empty dictionary with them to get an desired output that looks like this:
letter_ordered_dict = {'a': ['armet'], 'c': ['cherry', 'concrete'], 'f': ['flyer', 'fly-swatter'],
'h': ['helmet'], 'v': ['violin']}
The way I am attempting this, to begin, is by obviously first grabbing the first elements of the original list with a comprehension:
list_split_by_first_element = [first_elm.split(',')[0] for elm in list_that_has_been_ordered]
list_split_by_first_element.sort()
This produces the output:
['armlet', 'cherry', 'concrete', 'flyer', 'flyer', 'fly-swatter', 'helmet', 'violin']
The part I am stuck on is how to group by these elements on their first letters and skip duplicates to generate the output above.
Is there a better way of doing this?
This should do the job:
import itertools
tmp = sorted(e.split(',')[0] for e in list_to_split) # list_split_by_first_element
letter_ordered_dict = {k:list(set(v)) for k,v in itertools.groupby(tmp, lambda item: item[0])}
Output result in letter_ordered_dict:
{'a': ['armlet'],
'c': ['concrete', 'cherry'],
'f': ['fly-swatter', 'flyer'],
'h': ['helmet'],
'v': ['violin']}
For this kind of scanning/aggregation problem, you generally need a loop rather than a list comprehension. Assuming list_split_by_first_element is sorted, this should work:
letter_ordered_dict = dict()
prev_word = ''
for word in list_split_by_first_element:
if word == prev_word:
# skip repeated words
continue
letter = word[0]
letter_ordered_dict.setdefault(letter, []).append(word)
Note that dict.setdefault either looks up the key or sets it to the specified value if it doesn't exist, which is exactly what you want here.
With a very long list or a lot of duplicate words, you may find it faster to sort the sublists rather than the full list. Then something like this could work:
list_to_split = ['flyer, black and white', 'flyer, blue', 'fly-swatter, black', 'helmet, heavy',
'armlet, silver and gold', 'cherry, black', 'violin, very old', 'concrete, grey']
set_dict = dict()
for phrase in list_to_split:
word, rest = phrase.split(',', 1)
set_dict.setdefault(word[0], set()).add(word)
letter_ordered_dict = {
letter: sorted(words)
for letter, words in set_dict.items()
}
If the sublists for each letter don't need to be sorted internally, you could save some time by replacing sorted with list in the second example.
So I've written a code from the point after getting the list_of_words
list_of_words = ['armlet', 'cherry', 'concrete', 'flyer', 'flyer', 'fly-swatter', 'helmet', 'violin']
list_of_words = list(set(list_of_words))
first_char_dict = dict()
for word in list_of_words:
if word[0] in first_char_dict:
first_char_dict[word[0]].append(word)
else:
first_char_dict[word[0]] = [word]
print(first_char_dict)
output : {'h': ['helmet'], 'v': ['violin'], 'f': ['fly-swatter', 'flyer'], 'c': ['cherry', 'concrete'], 'a': ['armlet']}
Though I would like to bring you notice to the point that you are selecting only one world while splitting the string. Is that what you need ?
Consider myself a beginner with Python. I'm trying to do something I've not quite done before and am completely stumping myself.
Hoping someone can give me a clue as which path to take on this.
I have a number of lists within a larger list.
I would like to iterate through the large list and modify data in each sub-list. There are a number of common variables within each list, but not all lists will be the same.
Example:
LIST = [
['Name: Dave', 'Age 28', 'Dogs', 'Football',],
['Name: Tony', 'Age 22', 'Beer', 'Star Wars', 'Hotdogs']
]
The end goal is to have 1 large list with each sublist converted to a dictionary.
Goal:
LIST = [
{'Dave' : { 'Age' : '28' } {'Likes' : ['Dogs', 'Football']}},
{'Tony' : { 'Age' : '22' } {'Likes' : ['Beer', 'Star Wars', 'Hotdogs']}}
]
The conversion to dictionary I will worry about later. But I am struggling to get my head around working with each sub-list in a loop.
Any ideas would be highly appreciated.
Thanks!
list2 = []
for el in list1:
list2.append( compute(el))
where compute is a method that will turn your list into the dictionary you want
result = {}
temp = {}
for x in LIST:
key = x[0][6:]
key_1 = x[1][:3]
value_1 = x[1][3:]
key_2 = 'Likes'
value_2 = x[2:]
temp[key_1] = value_1
temp[key_2] = value_2
result[key] = temp
temp = {}
Try this
but as you know dictionary has no sequence , no guarantee for age to be second in dictionary
Here's an answer to get your dictionary in both the ways mentioned by Tom Ellis.
LIST = [
['Name: Dave', 'Age 28', 'Dogs', 'Football', ],
['Name: Tony', 'Age 22', 'Beer', 'Star Wars', 'Hotdogs']
]
l = list()
for li in LIST:
d = dict()
likes_list = []
for i in li:
if "name" in i.lower():
d.update(dict([i.replace(' ', '').split(":")])) #removing the whitespace for formatting.
elif "age" in i.lower():
d.update(dict([i.split()]))
else:
likes_list.append(i)
d["likes"] = likes_list
l.append(d)
print l
Which results in:
>>> [{'Age': '28', 'Name': 'Dave', 'likes': ['Dogs', 'Football']}, {'Age': '22', 'Name': 'Tony', 'likes': ['Beer', 'Star Wars', 'Hotdogs']}]
If you really want the dictionary in the format you stated first, you could continue with the program like this:
l2 = []
for element in l:
nd = {}
name = element.pop("Name").strip()
nd[name] = element
# print nd
l2.append(nd)
print l2
Which results in the way you stated:
>>> [{'Dave': {'Age': '28', 'likes': ['Dogs', 'Football']}}, {'Tony': {'Age': '22', 'likes': ['Beer', 'Star Wars', 'Hotdogs']}}]
Axnyff's answer is pretty much what you want
ShadowRanger's comment on Axnyff's answer is definitely what you want. List comprehensions are really cool!
Simply iterating over the list with a for loop lets you work on each sub-list and do whatever you want to it.
It looks like you don't really want to modify the lists in place, rather you want to process each list into a dictionary (and extracting that process into a separate function is very good for readability), and put those new dictionaries into a new list.
EDIT:
Also, as correctly mentioned in a down-voted answer, your dictionaries should probably be in the form:
{'Name': 'Dave', 'Age': 28, 'Likes': ['Dogs', 'Football']}
Unless you actually want to use the dictionary to find their information by their name, in which case this is the correct syntax:
{'Dave' : { 'Age' : 28, 'Likes' : ['Dogs', 'Football']}}
LIST=[{'Name': 'Dave', 'Age': 28, 'likes':['Dogs', 'Football']},{'Name': 'Tony', 'Age': 22, 'likes':['Beer', 'Star Wars', 'Hotdogs']}]
You Do like This, Thank You.
I have a list of names called names. I also have 2 dictionaries that contain a list of nested dictionaries that both have the key names and other data associated with the name. What I want to do is check that the name from the list is in one of the 2 dictionaries, if so, print the data associated only with that name. I can't find any of this stuff in the python docs
names = ['barry','john','george','sarah','lisa','james']
dict1 = {'results':[{'name':'barry','gpa':'2.9','major':'biology'},
{'name':'sarah','gpa':'3.2','major':'economics'},
{'name':'george','gpa':'2.5','major':'english'}]}
dict2 = {'staff':[{'name':'john','position':'Lecturer','department':'economics'},
{'name':'lisa','position':'researcher','department':'physics'},
{'name':'james','position':'tutor','department':'english'}]}
for x in names:
if x in dict1:
print gpa associated with the name
elif x in dict2:
print position associated with the name
The structure you're using for the two dicts isn't very optimal - each contains only a single element, which is a list of the relevant data for each person. If you can restructure those with a separate element per person using the name as a key, this becomes a trivial problem.
dict1 = {'barry': {'gpa':'2.9','major':'biology'},
'sarah': {'gpa':'3.2','major':'economics'},
'george': {'gpa':'2.5','major':'english'}}
dict2 = {'john': {'position':'Lecturer','department':'economics'},
'lisa': {'position':'researcher','department':'physics'},
'james': {'position':'tutor','department':'english'}}
Since it appears you can't get the data in this format, you'll have to convert it:
dict_results = dict((d['name'], d) for d in dict1[results])
if name in dict_results:
print dict_results[name]['gpa']
for _name in names:
if _name in [person['name'] for person in dict1['results']]: pass
elif _name in [person['name'] for person in dict2['staff']]:pass
something like that at least
This should get you an idea:
for name in names:
print name, ":"
print "\t", [x for x in dict2["staff"] if x["name"] == name]
print "\t", [x for x in dict1["results"] if x["name"] == name]
prints
barry :
[]
[{'major': 'biology', 'name': 'barry', 'gpa': '2.9'}]
john :
[{'department': 'economics', 'position': 'Lecturer', 'name': 'john'}]
[]
george :
[]
[{'major': 'english', 'name': 'george', 'gpa': '2.5'}]
sarah :
[]
[{'major': 'economics', 'name': 'sarah', 'gpa': '3.2'}]
lisa :
[{'department': 'physics', 'position': 'researcher', 'name': 'lisa'}]
[]
james :
[{'department': 'english', 'position': 'tutor', 'name': 'james'}]
[]
If you get this data from a database, you should probably rather work on the SQL frontier of the problem. A database is made for operations like that.
names = ['barry','john','george','sarah','lisa','james']
dict1 = {'results':[{'name':'barry','gpa':'2.9','major':'biology'},
{'name':'sarah','gpa':'3.2','major':'economics'},
{'name':'george','gpa':'2.5','major':'english'}]}
dict2 = {'staff':[{'name':'john','position':'Lecturer','department':'economics'},
{'name':'lisa','position':'researcher','department':'physics'},
{'name':'james','position':'tutor','department':'english'}]}
import itertools
for x in itertools.chain(dict1['results'], dict2['staff']):
for n in names:
if n in x.values():
print x
or the 2nd part could be:
ns = set(names)
for x in itertools.chain(dict1['results'], dict2['staff']):
if x['name'] in ns:
print x