I have a list with movie names:
Movie List
And another list of questions about movies:
List of questions
My objective is to loop through the list of questions and each time the function finds a name in the question that is in the list of movies, changes the name to "MOVIE".
At the moment i can do it for each question:
def remove_movie_name_1(text):
for i in tqdm(range(len(movies))):
return re.sub(movies[42], 'MOVIE', text)
remove_movie_name_1(tq[21])
This way i can change it for example from "What was the role played by Tim Allen in Toy Story 3?" to "What was the role played by Tim Allen in MOVIE?"
When i tried to apply it to the whole list I used this code:
def remove_movie_name(text):
for i in tqdm(range(len(movies))):
return re.sub(movies[i], 'MOVIE', text)
for i in tqdm(range(len(tq))):
tq[i] = remove_movie_name(tq[i])
But this code doesn't change anything and I can't see what's the problem.
Thank you.
def remove_movie_name(text):
for i in tqdm(range(len(movies))):
return re.sub(movies[i], 'MOVIE', text)
return exits the function immediately. Your loop only runs one time.
Related
I'm making a program that allows the user to log loot they receive from monsters in an MMO. I have the drop tables for each monster stored in text files. I've tried a few different formats but I still can't pin down exactly how to take that information into python and store it into a list of lists of lists.
The text file is formatted like this
item 1*4,5,8*ns
item 2*3*s
item 3*90,34*ns
The item # is the name of the item, the numbers are different quantities that can be dropped, and the s/ns is whether the item is stackable or not stackable in game.
I want the entire drop table of the monster to be stored in a list called currentDropTable so that I can reference the names and quantities of the items to pull photos and log the quantities dropped and stuff.
The list for the above example should look like this
[["item 1", ["4","5","8"], "ns"], ["item 2", ["2","3"], "s"], ["item 3", ["90","34"], "ns"]]
That way, I can reference currentDropTable[0][0] to get the name of an item, or if I want to log a drop of 4 of item 1, I can use currentDropTable[0][1][0].
I hope this makes sense, I've tried the following and it almost works, but I don't know what to add or change to get the result I want.
def convert_drop_table(list):
global currentDropTable
currentDropTable = []
for i in list:
item = i.split('*')
currentDropTable.append(item)
dropTableFile = open("droptable.txt", "r").read().split('\n')
convert_drop_table(dropTableFile)
print(currentDropTable)
This prints everything properly except the quantities are still an entity without being a list, so it would look like
[['item 1', '4,5,8', 'ns'], ['item 2', '2,3', 's']...etc]
I've tried nesting another for j in i, split(',') but then that breaks up everything, not just the list of quantities.
I hope I was clear, if I need to clarify anything let me know. This is the first time I've posted on here, usually I can just find another solution from the past but I haven't been able to find anyone who is trying to do or doing what I want to do.
Thank you.
You want to split only the second entity by ',' so you don't need another loop. Since you know that item = i.split('*') returns a list of 3 items, you can simply change your innermost for-loop as follows,
for i in list:
item = i.split('*')
item[1] = item[1].split(',')
currentDropTable.append(item)
Here you replace the second element of item with a list of the quantities.
You only need to split second element from that list.
def convert_drop_table(list):
global currentDropTable
currentDropTable = []
for i in list:
item = i.split('*')
item[1] = item[1].split(',')
currentDropTable.append(item)
The first thing I feel bound to say is that it's usually a good idea to avoid using global variables in any language. Errors involving them can be hard to track down. In fact you could simply omit that function convert_drop_table from your code and do what you need in-line. Then readers aren't obliged to look elsewhere to find out what it does.
And here's yet another way to parse those lines! :) Look for the asterisks then use their positions to select what you want.
currentDropTable = []
with open('droptable.txt') as droptable:
for line in droptable:
line = line.strip()
p = line.find('*')
q = line.rfind('*')
currentDropTable.append([line[0:p], line[1+p:q], line[1+q:]])
print (currentDropTable)
I am trying to append a random choice into a dictionary, but my code doesn't seem to be working.
The file I am using (mood.txt):
happy, Jennifer Clause
happy, Jake Foster
sad, Jonathan Bower
mad, Penny
excited, Logan
awkward, Mason Tyme
my code:
def theFile():
moodFile = open("mood.txt")
theMood = moodFile.readlines()
moodFile.close()
return(theMood)
def makeTheDict(myFile):
moodDict = {}
for lines in myFile:
(mood, name) = lines.split(",")
moodDict[mood] = name.strip()
return(moodDict)
def randomMood(name, mood, moodDict):
if mood in moodDict:
randomMood = random.choice(mood)
moodDict[mood] = randomMood
moodDict.append(name, randomMood)
print(name, "has been put in the", randomMood, "group")
def main():
moodFile = theFile()
moodDict = makeTheDict(moodFile)
name = input("Choose a name: ")
newMood = input("Choose a mood: ")
randomMood(name, newMood, moodDict)
For example, I want to add a "Jamie Green" into a random group, and if it randomly chose "sad" then -
happy, Jennifer Clause
happy, Jake Foster
sad, Jonathan Bower
mad, Penny
excited, Logan
awkward, Mason Tyme
#sad, Jamie Green
How would I append this into the dictionary randomly?
Thank you!
It seems that you want to map strings to lists of strings, but instead of that you are mapping strings to strings.
Look at this line:
moodDict[mood] = name.strip()
Here you are mapping the string mood to the string name.strip(). If at this point, there was already a name mapped to the current mood, the old value would be replaced and lost. In your file sample, both Jennifer and Jake are happy. At the first iteration of the for loop you have:
moodDict["happy"] = "Jennifer Clause"
Then, at the second step, you have.
moodDict["happy"] = "Jake Foster"
Here "Jake Foster" replaces "Jennifer Clause". Since the moods can be repeated, what you probably want is something like this:
if mood in moodDict:
moonDict[mood].append(name.strip())
else:
moonDict[mood] = [name.strip()]
This way, for each mood key you have a list of name values.
Regarding the randomMood function, there are may things doesn't look good:
The if statement should be indented since is part of the function. This should throw an IndentationError, but I will assume it happened when you copied the code into StackOverflow.
Mood is a string, so what you are actually doing in random.choice(mood) is to choose a random character from that string, which doesn't make any sense. You probably want to choose from the list of moods, which would be something like this randomMood = random.choice(moodDict.keys()).
Because of what I explained in the previous point, the following line just replace the value under the mood key with a random character from the mood, which doesn't make sense.
Dictionaries don't have any method named append, this should throw an error too. You probably want to replace it with this: moonDict[randomMood].append(name)
Finally, I don't understand why you ask the user to input a mood when it is supposed to be chosen randomly.
It seems you are a bit confused about what a Python dictionary is and how it works. Remember that it map keys to values. In your code your keys are the moods and the values are the names, both represented as strings. The keys are unique. This means that if you assign a new value to an existing key, the old value mapped under that key gets lost. If you want to deal with multiple values under the same key you should map the key to a collection of values, like a list, instead of a single value.
Using Python 3.3
Hi, I'm pretty new to programming/Python, so please don't go into too in-depth/complex methods of solving this problem.
I have a dictionary in which the keys are the person's name, and each of the key's values is a list of the names of the person's friends. For example:
friends_of_person = {'Albus': ['Ron', 'Hermione'], 'Harry': ['Ron', 'Hermione', 'Neville']}
This dictionary can be longer.
What my question is, how do I write a for loop or code that will loop through the values and compare each of the values to each of the values of another key's values. To make this clearer, let's use the above example. Albus is a friend to Harry, Ron, and Hermione. Harry is a friend to Ron and Hermione.
But I want to compare 'Ron' to the 'Ron', 'Hermione', and 'Neville' from the key Harry.
And then what I want is to see if 'Ron' is a friend of Harry. IF and ONLY if Ron is a friend of Harry, then I want to make 'Harry' as a potential friend of 'Albus'. The case applies to when comparing 'Hermione' to the 'Ron' and 'Hermione' from Harry's values. - this is like mutual friends.
The following is the code I've written, but it didn't seem to yield the correct answer.
friends_of_person = {'Albus': ['Ron', 'Hermione'], 'Harry': ['Ron', 'Hermione', 'Neville']}
for person in friends_of_person:
friends_list = friends_of_person[person]
for friend in friends_list:
recommendation = ''
for another_person in friends_of_person:
if friend in friends_of_person[another_person]:
recommendation = another_person
It doesn't seem correct. But if anyone can give me hints/tips to put me on the right direction, it'll be greatly appreciated!
Thank you in advance :)
Use set to check the intersection of people's friend list:
In [352]: lst1=friends_of_person['Albus']
In [353]: lst2=friends_of_person['Harry']
In [354]: lst1
Out[354]: ['Ron', 'Hermione']
In [355]: lst2
Out[355]: ['Ron', 'Hermione', 'Neville']
In [356]: set(lst1)&set(lst2)
Out[356]: set(['Hermione', 'Ron'])
If you want approach using only simple iterations and basic features, here you go:
for friend in friends_of_person['Albus']:
recommendation = []
for person, friends in friends_of_person.items():
if person == 'Albus':
continue # we don't need anyone who already is his friend
for potential in friends:
if potential in friends_of_person['Albus'] and potential not in recommendation:
recommendation.append(potential)
print(potential)
...:
Neville
PS. It's ugly, but that's what OP wanted...
#zhangxaochen's answer using sets is in my opinion the neatest. Nonetheless, if you want to use lists you could do something like:
friends = {'Albus': ['Ron', 'Hermione'], 'Harry': ['Ron', 'Hermione', 'Neville']}
def mutual_friends(a, b):
return [x for x in friends[a] if x in friends[b]]
Note that's re-coding set intersection (EDIT: if you have been instructed not to use set intersection then this solution is good since you code it yourself :)).
So
def recommendations(x):
result = []
for f in friends.keys():
if f != x and mutual_friends(x, f) > 1:
result.append(f)
return result
Basically, for a given person x, find all the people that have more than one mutual friend with them. You could change it to == 2 if you want exactly 2 mutual friends.
This question already has answers here:
Dictionary Help! Extracting values and making a table
(2 answers)
Closed 8 years ago.
Here's the question that I'm supposed to code for:
Write the contract, docstring and implementation for a function showCast that takes a movie title and prints out the characters with corresponding actors/actresses from the given movie in an alphabetical order of characters. The columns must be aligned (20 characters (including the character's name) before the name of the actor/actress.) If the movie is not found, it prints out an error message.
It gives an example of what's supposed to happen here
>>> showCast("Harry Potter and the Sorcerer's Stone")
Character Actor/Actress
----------------------------------------
Albus Dumbledore Richard Harris
Harry Potter Daniel Radcliffe
Hermione Granger Emma Watson
Ron Weasley Rupert Grint
>>> showCast('Hairy Potter')
No such movie found
Here are other functions that I've written for the same project that will probably be of assistance in answering the question. A summary of what I've had to do so far is that I'm creating a dictionary, called myIMDb, with a key of the title of the movie, and the value another dictionary. In that dictionary that key is a character of a movie, and the value is the actor. And I've done stuff with it. myIMDb is a global variable for the record.
Other functions, what they do is the docString
def addMovie (title, charList, actList):
"""The function addMovie takes a title of the movie, a list of characters,
and a list of actors. (The order of characters and actors match one
another.) The function addMovie adds a pair to myIMDb. The key is the title
of the movie while the value is a dictionary that matches characters to
actors"""
dict2 = {}
for i in range (0, len(charList)):
dict2 [charList[i]] = actList[i]
myIMDb[title] = dict2
return myIMDb
I've added three movies,
addMovie("Shutter Island", ["Teddy Daniels", "Chuck Aule"],["Leonardo DiCaprio, ","Mark Ruffalo"])
addMovie("Zombieland", ["Columbus", "Wichita"],["Jesse Eisenberg, ","Emma Stone"])
addMovie("O Brother, Where Art Thou", ["Everett McGill", "Pete Hogwallop"],["George Clooney, ","John Turturro"])
def listMovies():
"""returns a list of titles of all the movies in the global variable myIMDb"""
return (list(myIMDb.keys()))
def findActor(title, name):
""" takes a movie title and a character's name and returns the
actor/actress that played the given character in the given movie. If the
given movie or the given character is notfound, it prints out an error
message"""
if title in myIMDb:
if name in myIMDb[title]:
return myIMDb[title][name]
else:
return "Error: Character not in Movie"
else:
return "Error: No movie found"
Now where I'm having trouble
I'm supposed to write the showCast function, but I'm having a lot of trouble. I've been tinkering with it for a while but when I call myIMDb.values() everything returns. And I can't seem to loop through it to sort them to create the table.
Here's what I've come up with so far, but it doesn't do what I was hoping. I'm just hoping that one of you can steer me in the right direction. (The commented out region is what I was doing before, just so you can see my train of thought. [the print(alist) and print(alist[0]) was just to confirm that it's one big entry in a list, not separated at all])
def showCast(title):
if title in myIMDb:
actList=[]
chList=[]
aList = list(myIMDb.values())
print (aList)
print (aList[0])
""""for i in range (len(aList)):
if i%2==0:
chList.append(aList[i])
else:
actList.append(aList[i])
print(chList)
print(actList)""""
else:
return "Movie not Found"
It's an old question, but I'll take a stab. I think your confusion comes from the nested nature of the myIMDb object. To get back information about a specific movies, you should use the title as a key to myIMDb, e.g. myIMDb[title]. What you get back is another dictionary, that you can then use to get the character/actor key value pairs.
Here's a working version of the showCast function:
def showCast(title):
if title in myIMDb:
print("{0:20} {1:20}".format("Character", r"Actor/Actress"))
print("-"*40)
for character, actor in myIMDb[title].items():
print("{0:20} {1:20}".format(character, actor))
else:
return "Movie not Found"
The first print statement generates the heading, and uses the Python's format string method to get the aligned spacing that you want. The next print statement is the divider, and then the meat of the function is simply iterating over the pairs with a for loop.
I hope that helps.
I have a list of names and addresses organized in the following format:
Mr and Mrs Jane Doe
Candycane Lane
Magic Meadows, SC
I have several blocks of data written like this, and I want to be able to alphabetize each block by the last name (Doe, in this case). After doing some digging, the best I can reckon is that I need to make a "List of lists" and then use the last name as a key by which to alphabetize the block. However, given by freshness to python and lack of Google skills, the closest I could find was this. I'm confused as to converting each block to a list and then slicing it; I can't seem to find a way to do this and still be able to alphabetize properly. Any and all guidance is greatly appreciated.
If I understood correctly, what you want basically is to sort values by "some computation done on the value", in this case the extracted last name.
For that, use the key keyword argument to .sort() or sorted():
def my_key_function(original_name):
## do something to extract the last name, for example:
try:
return original_name.split(',')[1].strip()
except IndexError:
return original_name
my_sorted_values = sorted(my_original_values, key=my_key_function)
The only requirement is that your "key" function is deterministic, i.e. always return the same output for each given input.
You might also want to sort by last name and then first name: in this case, just return a tuple (last, first): if last si the same for two given items, first will be used to further sort the two.
Update
For your specific case, this function should do the trick:
def my_key_function(original_name):
return original_name.splitlines()[0].split()[-1]
Assuming you already have the data in a list
l = ['Mr and Mrs Jane Smith\nCandycane Lane\nMagic Meadows, SC',
'Mr and Mrs Jane Doe\nCandycane Lane\nMagic Meadows, SC',
'Mr and Mrs Jane Atkins\nCandycane Lane\nMagic Meadows, SC']
You can specify the key to sort on.
l.sort(key=lambda x: x.split('\n')[0].split(' ')[-1])
In this case, get the last word (.split(' ')[-1]) on the first line (.split('\n')[0])
you want to make a new list where each entry is a tuple containing the sort key you want and the whole thing. Sort that list and then get the second component of each entry in the sort:
def get_sort_name (address):
name, address, city = address.split('\n')
return (name.split(' ')[-1] , address) # last item of first line & whole thing as tulle
keyed_list = map (get_sort_name, addresses)
keyed_list.sort()
sorted_addresses = [item[1] for item in keyed_list]
Thi could be more compact using lambdas of course but its better to be readable :)