Usage of a dictionary, Right or wrong? - python

I'm creating a car sales program and need to use a dictionary, I have a basic understanding of them. Would it be efficient to hold the car name as a string for the key, then store the relevant cars selling price in the values through a list? for example,
Audi1Price = 1000
Audi2Price = 1500
Cars = ["Audi": [Audi1Price, Audi2Price]]
Can this work? Is there a better usage for the dictionary?
Maybe there's a better way to work with the selling price as I'd like to print it out too, I'm unsure. Thanks

Yes, that could work.
There is a problem in your example code, though: you used [] instead of {} for the dictionary.
You need to do this:
Audi1Price = 1000
Audi2Price = 1500
Cars = {
"Audi": [Audi1Price,Audi2Price]
}

Related

Python - List of lists - S&P500

I am new to python and am looking to analyze the S&P500 by sector. I have assigned symbols to all 11 sectors in the S&P with the first two looking like:
Financials = ['AFL', 'AIG', .... 'ZION']
Energy = ['APA', 'BKR', ... 'SLB']
I then create a new list (of lists) which might look like:
sectors_to_analyze = [Financials, Energy] or [Materials, ConsumerStaples]
My analysis is working perfectly, but I want to retrieve the names "Financials" and "Energy" to attach to the data produced and I cannot figure out how to do it other than make the name part of the list (Financials = ['Financials','AFL', 'AIG', .... 'ZION']
Can someone please point me in the right direction? Thank you.
Perhaps you could use a dictionary
sectors = {
'Financials':['AFL', ...],
# rest of your lists
}
Then you can iterate over the whole dict and access both names and data associated with those names
for key, value in sectors.items():
print(f'Sector name: {key}, List: {value}')
I think you want to use a dictionary instead of a "list of lists" (also called a two dimensional list). You could then loop over the dictionary almost the same way. Here's some example code:
Financials = ['AFL', 'AIG', 'ZION']
Energy = ['APA', 'BKR', 'SLB']
sectors = {"Finacials": Financials, "Energy": Energy}
# in this loop, sector is the sector's name, and symbols is the sector's
# list
for sector in sectors:
symbols = sectors[sector]
# ...
# do some analysis
# ...

How to reference a specific part of a dictionary in Python

Alright, so I am trying to create a simple thing that will tell me the showtimes of the movies at the theatre, the names of the movies, and the Rotten Tomatoes score in Python, but I am having a hard time figuring out how to get the meterScore.
actorCount = 0
actors = []
criticCount = 0
critics = []
franchiseCount = 0
franchises = []
movieCount = 3
movies = [{'name': 'Frozen II', 'year': 2019, 'url': '/m/frozen_ii', 'image': 'https://resizing.flixster.com/QZg2MuPQoRlWcWYAwufbQBlv-I0=/fit-in/80x80/v1.bTsxMzIwMzIxODtqOzE4Mjg3OzEyMDA7NTQwOzgxMA', 'meterClass': 'certified_fresh', 'meterScore': 76, 'castItems': [{'name': 'Kristen Bell', 'url': '/celebrity/kristin_bell'}, {'name': 'Idina Menzel', 'url': '/celebrity/idina_menzel'}, {'name': 'Josh Gad', 'url': '/celebrity/josh_gad'}], 'subline': 'Kristen Bell, Idina Menzel, Josh Gad, '}]
tvCount = 0
tvSeries = []
What I am trying to get from that list of data is the meterScore, if you scroll over to the right far enough you can see it. All this data is part of a bigger dictionary, which I named resultOne, but I don't think that matters. I just need some help figuring out how to reference and get the meterScore from the dictionary, so I can print it out, so when I want to see what movies and what rating they got I can just run this program and it will do it for me. I don't really use dictionaries that much, but the library I am using to get the Rotten Tomato data creates it as this very hard to reference dictionary, so any help is appreciated! What I don't get is that if I try to print(resultOne.movies) it says that that is not an attribute or something to that affect, even though when I put it into something that will print out the keys and values, such as I did to get the code above, it clearly shows it is a key. I also tried to print(resultOne.movies[meterScore]), but that didn't work either.
Dictionary values are looked up by their keys using [], not ..
Now, the trick is that the movies key points to a list. So you need to mix two kinds of indexing that both use []: dictionary indexing, which is by key, and list indexing, which is by position in the list (starting at 0).
Ultimately, you want to do this:
score = resultOne['movies'][0]['meterScore']
^ ^ ^
| | |
lookup in outer dict | |
first item in list |
lookup in inner dict
Try this:
movies[0]['meterScore']
# 76
Why don't you try something like this to extract every meterScore from all the movies in the dictionary:
listOfAllMeterScores = [ movie['meterScore'] for movie in movies ]
In that snippet, movies is a list containing a dict. So index the list then index the dict:
movies[0]['meterScore']
If movies might contain more than one item (or zero for that matter), iterate over it instead to get a list of the meterScores:
meter_scores = [movie['meterScore'] for movie in movies]

Python: Compare values from 2 dictionaries with the same key

Hello i am new to python and i have a question about dictionaries:
Let's say we have a dictionary :
Cars {"Audi": {"Wheels": 4, "Body": 1, "Other": 20},"Ford": {"Wheels": 2, "Body": 3, "Other":10},"BMW": {"Wheels": 5, "Body": 0.5, "Other": 30}}
And and other dictionary:
Materials {"Wheels": 30, "Body": 5, "Other": 110}
I want to return the number of cars i can produce with the materials i have so:
def production(car,Materials):
return
production("Audi",Materials)
My output in this example should return the number 5,because there are only 5 body parts to use.
I was thinking to make it somehow like this:
Divide the values from Materials with values from cars. Then write the numbers to an other list ,and then return the min number in whole.
More exaples:
production("BMW",Materials)
3.0 # because the value of key only is 110 and for 3 cars we need 90 other:
production("Ford",Materials)
1.0 # because the value of key body is 3 and for 1 car we need 3 body:
I thank you in advance for everything.
If what you want is to see how many of any given car can be created without actually affecting the contents of Materials, you could write your method like so:
def number_of_units_creatable(car_key):
required_parts = Cars[car_key]
return min(Materials["Wheels"] // required_parts["Wheels"],
Materials["Body"] // required_parts["Body"],
Materials["Other"] // required_parts["Other"])
In production, you'd want to add conditional guards to check whether your Cars and Materials have all the required keys. You'll get an exception if you try to get the value for a key that doesn't exist.
This will allow you to figure out the maximum number of any given car you can create with the resources available in Materials.
I'd strongly recommend you not use nested dicts like this, though - this design would be greatly helped by creating, say, a Materials class, and storing this as your value rather than another dictionary. abarnert has a little more on this in his post.
Another note, prompted by abarnert - it's an extremely bad idea to rely on all a shared, static set of keys between two separate dictionaries. What happens if you want to build, say, an armored car, and now you need a gun? Either you have to add Gun: 0 within the required attributes of every car, or you'll run into an exception. Every single car will require an entry for every single part required by each and every car in existence, and a good deal of those will signify nothing other than the fact that the car doesn't need it. As it stands, your design is both very constraining and brittle - chance are good it'll break as soon as you try and add something new.
If the set of possible materials is a static collection—that is, it can only have "Wheels", "Body", and "Other"—then you really ought to be using a class rather than a dict, as furkle's answer suggests, but you can fake it with your existing data structure, as his answer shows.
However, if the set of possible materials is open-ended, then you don't want to refer to them one by one explicitly; you want to loop over them. Something like:
for material, count in car.items():
In this case:
return min(Materials[material] // count for material, count in car.items())
You can iterate over materials and decrement the values until one become 0:
def production(car, materials):
count = 0
while 0 not in materials.values():
for part in cars[car]:
materials[part] -= 1
count += 1
return count
If you don't want to change the material dict:
def production(car, materials):
count = 0
vals = materials.values()
while not 0 in vals:
for ind, part in enumerate(Cars[car]):
vals[ind] -= 1
count += 1
return count

Django, filter and group query results by a field

I have this working but I'm sure there must be a better method
The context is a movie/television app so there are titles (movies/tv) and people who act in each, many to many relationship.
I have a "titlepeople" model with information such as:
id, people_fk, title_fk, role_title
On movies where a cast member has alot of roles I need to display their information like:
Tom Hanks: Gardener, Police Man #1, Another Role #4
Is there anyway I can optimize the below way of doing this so the code isn't so lengthy?
cast_unique = list()
for person in cast:
#if not in the unique list, add them
if person.people not in [p.people for p in cast_unique]:
cast_unique.append(person)
else:
# if in the list, append the role information
if person.role_title:
for c in cast_unique:
if c.people == person.people:
# append role info
c.role_title = '{0} / {1}'.format(c.role_title, person.role_title)
Thanks
You should change cast_unique to be a dictionary where you use the cast member as the key. This will allow much greater performance because you won't have to iterate the cast_unique iterable.
Also, your use a list comprehension in the if person.people not in [p.people for p in cast_unique]: requires an entire list to be create of people for every iteration for the test; which, could use a lot of memory plus there's no way to short circuit the list comprehension when a match occurs. Still a dictionary is a much better data type to use for this situation.
cast_unique = {}
for person in cast:
if person.people not in cast_unique:
cast_unique[person.people] = person
else:
cast_unique[person.people].role_title = '{0} / {1}'.format(cast_unique[person.people].role_title, person.role_title)

Maintaining order in large list of movies/ratings

I have a text file with hundreds of thousands of students, and their ratings for certain films organized with the first word being the student number, the second being the name of the movie (with no spaces), and the third being the rating they gave the movie:
student1000 Thor 1
student1001 Superbad -3
student1002 Prince_of_Persia:_The_Sands_of_Time 5
student1003 Old_School 3
student1004 Inception 5
student1005 Finding_Nemo 3
student1006 Tangled 5
I would like to arrange them in a dictionary so that I have each student mapped to a list of their movie ratings, where the ratings are in the same order for each student. In other words, I would like to have it like this:
{student1000 : [1, 3, -5, 0, 0, 3, 0,...]}
{student1001 : [0, 1, 0, 0, -3, 0, 1,...]}
Such that the first, second, third, etc. ratings for each student correspond to the same movies. The order is completely random for movies AND student numbers, and I'm having quite a bit of trouble doing this effectively. Any help in coming up with something that will minimize the big-O complexity of this problem would be awesome.
I ended up figuring it out. Here's the code I used for anyone wondering:
def get_movie_data(fileLoc):
movieDic = {}
movieList = set()
f = open(fileLoc)
setHold = set()
for line in f:
setHold.add(line.split()[1])
f.close()
movieList = sorted(setHold)
f = open(fileLoc)
for line in f:
hold = line.strip().split()
student = hold[0]
movie = hold[1]
rating = int(hold[2])
if student not in movieDic:
lst = [0]*len(movieList)
movieDic[student] = lst
hold2 = movieList.index(movie)
rate = movieDic[student]
rate[hold2] = rating
f.close()
return movieList, movieDic
Thanks for the help!
You can first build a dictionary of dictionaries:
{
'student1000' : {'Thor': 1, 'Superbad': 3, ...},
'student1001' : {'Thor': 0, 'Superbad': 1, ...},
...
}
Then you can go through that to get a master list of all the movies, establish an order for them (corresponding to the order within each student's rating list), and finally go through each student in the dictionary, converting the dictionary to the list you want. Or, like another answer said, just keep it as a dictionary.
defaultdict will probably come in handy. It lets you say that the default value for each student is an empty list (or dictionary) so you don't have to initialize it before you start appending values (or setting key-value pairs).
from collections import defaultdict
students = defaultdict(dict)
with open(filename, 'r') as f:
for line in f.readlines():
elts = line.split()
student = elts[0]
movie = elts[1]
rating = int(elts[2])
students[student][movie] = rating
So, the answers here are functionally the same as what you seem to be looking for, but as far as directly constructing the lists you're looking for, they seem to be answering slightly different questions. Personally I would prefer to do this in a more dynamic way. Since it doesn't seem to me like you actually know the movies that are going to be rated ahead of time, you've gotta keep some kind of running tally of that.
ratings = {}
allMovies = []
for line in file:
info = line.split(" ")
movie = info[1].strip().lower()
student = info[0].strip().lower()
rating = float(info[2].strip().lower())
if movie not in allMovies:
allMovies.append(movie)
movieIndex = allMovies.index(movie)
if student not in ratings:
ratings[student] = ([0]*(len(allMovies)-1)).append(rating)
else:
if len(allMovies) > len(ratings[student]):
ratings[student] = ratings[student].extend([0]*(len(allMovies)-len(ratings[student]))
ratings[student][movieIndex] = rating
It's not the way I would approach this problem, but I think this solution is closest to the original intent of the question and you can use a buffer to feed in the lines if there's a memory issue, but unless your file is multiple gigabytes there shouldn't be an issue with that.
Just put the scores into a dictionary rather than a list. After you've read all the data, you can then extract the movie names and put them in any order you want. Assuming students can rate different movies, maintaining some kind of consistent order while reading the file, without knowing the order of the movies to begin with, seems like a lot of work.
If you're worrying about the keys taking up a lot of memory, use intern() on the keys to make sure you're only storing one copy of each string.

Categories

Resources