Python Forum
Add elements to a Dictionary
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Add elements to a Dictionary
#1
Greetings,

I am trying to loop through a list of move titles and their corresponding rating. ex.

Title = 'Rocky', Rating = 5

How can I continue to add more titles and associative rating to the dictionary without overwriting?

mydict = {'Rocky': 5, 'Rocky II': 4,...}
Something like that? or how would I do it with title and rating keys? Nested?
I am looking for something similar to a lists append method.
I want to be able to iterate over this dictionary when it's full.

Thanks in advance
Matt
Reply
#2
I'm not sure I understand the question. Does this work for you?
mydict['Rocky 3'] = -1
I am confused about "overwriting". Do you mean that you don't want to add a movie if it already exists in the dictionary, or do you mean you want to add the movie without it replacing the existing dictionary entry for that same movie? If the latter, that is not what dictionaries are for and you would be better off making a list of tuples (or named tuples).

Another possibility is that instead of mapping movie titles to a rating, you map the movie title to a list of ratings. If you have multiple ratings for the same movie you just append the rating to the list of ratings. I did something like that recently responding to a post about poker hands. I wanted to group cards by suit and by rank, so I subclassed dictionary to create keyed groups (lists).
class Grouper(dict):
    '''I am like a dictionary, but I can map multiple values to the same key'''
    def __init__(self, items=[]):
        super().__init__()
        for item in items:
            self[item[0]] = item[1]
 
    def __setitem__(self, key, value):
        group = self.get(key, [])
        group.append(value)
        super().__setitem__(key, group)
  
    def most_common(self):
        '''Return items sorted in decreasing order by count'''
        items = list(super().items())
        items.sort(key=lambda item: len(item[1]), reverse=True)
        return items

movies = Grouper((('Rocky',  5),  ('Rocky II', 4), ('Rocky',  3))
movies['Rocky'] would return a list of ratings for the movie: [5, 3]
Reply
#3
(Sep-08-2021, 07:29 PM)muzikman Wrote: Greetings,

I am trying to loop through a list of move titles and their corresponding rating. ex.

Title = 'Rocky', Rating = 5
You mention a list and then there is an ex. that is not a list or maybe you just missed the [] and the correct formatting?

(Sep-08-2021, 07:29 PM)muzikman Wrote: How can I continue to add more titles and associative rating to the dictionary without overwriting?

mydict = {'Rocky': 5, 'Rocky II': 4,...}
Something like that? or how would I do it with title and rating keys? Nested?
I am looking for something similar to a lists append method.
I want to be able to iterate over this dictionary when it's full.

Thanks in advance
Matt
Then ask about a dict, do you have a list and a dict or maybe only a dict ?

Please are you able to make clear what your starting data is, how you want to alter it and what it should look like afterwards?
Reply
#4
(Sep-08-2021, 07:29 PM)muzikman Wrote: Greetings,

I am trying to loop through a list of move titles and their corresponding rating. ex.

Title = 'Rocky', Rating = 5

How can I continue to add more titles and associative rating to the dictionary without overwriting?

mydict = {'Rocky': 5, 'Rocky II': 4,...}
Something like that? or how would I do it with title and rating keys? Nested?
I am looking for something similar to a lists append method.
I want to be able to iterate over this dictionary when it's full.

Thanks in advance
Matt

I was thinking, I could also do something like this, make a list of tuples or a tuple of tuples.

mylist=[('Rocky',5), ('Rocky II', 4)]
mylist.append(('Scary Movie', 2))
for x,y in mylist:
    print(x,y)
Reply
#5
There are lot of ambiguity for me, so just some examples of dict and EAFP:

>>> ratings = {'Peppa the Pig': 5}
>>> ratings.update([('Bob the Builder', 10)])
>>> ratings
{'Peppa the Pig': 5, 'Bob the Builder': 10}
>>> try:
...     print(ratings['Fireman Sam'])
... except KeyError:
...     print('No rating for this movie')
...
No rating for this movie
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#6
Have to structure it different to make some sense.
A basic example with a nested dictionary.
>>> from pprint import pprint
>>>
>>> movies = {'movie1': {'Title': 'Rocky', 'Rating': 5}, 'movie2': {'Title': 'Rocky3', 'Rating': 4}}
>>>
>>> # Add
>>> movies['movie3'] = {'Title': 'First blood', 'Rating': 6}
>>> pprint(movies)
{'movie1': {'Rating': 5, 'Title': 'Rocky'},
 'movie2': {'Rating': 4, 'Title': 'Rocky3'},
 'movie3': {'Rating': 6, 'Title': 'First blood'}}

>>> # Search
>>> find_movie = 'First blood'
>>> for movie_id, movie_info in movies.items():
...     if find_movie in movie_info['Title']:
...         print(movie_info)
{'Title': 'First blood', 'Rating': 6}

>>> for movie_id, movie_info in movies.items():
...     if 'First blood' in movie_info['Title']:
...         print(f"Found <{movie_info.get('Title')}> with a rating of <{movie_info.get('Rating')}>")
Found <First blood> with a rating of <6>

Database can come to mind when doing this,a demo of a easy way with dataset.
import dataset

movies = [
    {'Title': 'Rocky', 'Rating': 5},
    {'Title': 'Rocky3', 'Rating': 4},
    {'Title': 'First blood', 'Rating': 6}
]

db = dataset.connect('sqlite:///movies.db')
table = db['movie_table']
for movie in movies:
    table.insert(movie)
>>> [m for m in db['movie_table']]
[OrderedDict([('id', 1), ('Title', 'Rocky'), ('Rating', 5)]),
 OrderedDict([('id', 2), ('Title', 'Rocky3'), ('Rating', 4)]),
 OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)])]
>>> 
>>> table.find_one(Title='First blood')
OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)])
>>> 
>>> # Have now also SQL queries
>>> [m for m in db.query("select * from movie_table order by Rating desc limit 3")]
[OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)]),
 OrderedDict([('id', 1), ('Title', 'Rocky'), ('Rating', 5)]),
 OrderedDict([('id', 2), ('Title', 'Rocky3'), ('Rating', 4)])]
Reply
#7
Wall Wall Wall Wall Wall Wall Wall Wall
Why complicate it?
mydict = dict()

Title = 'Rocky'; Rating = 5

for n, i in enumerate(range(Rating, 0, -1), start = 1):
    mydict[f"{Title}{n}"] = i

print(mydict)
Output:
{'Rocky1': 5, 'Rocky2': 4, 'Rocky3': 3, 'Rocky4': 2, 'Rocky5': 1}
Quote:Don't just show off how powerful your code is, please try to make it easy to understand, I love Khaby
Reply
#8
From the responses I don't think anyone understands the original request,
Reply
#9
I apologize to everyone. I was very tired when I wrote the post. Because I confused you, I am confused when I see your examples. LOL!

Basically, I am learning about scraping with BeautifulSoup using books.toscrape.com. I am following a book but wanted to try and figure it out before the author revealed the answer. I already know what I am going to do and that is, use a tuple. But I will show you the code anyway:
No comments on the code, I am following a book.

import requests
import bs4
# Grab all books from every page with a rating of 2
def soup_request(page_num, base_url):
    res = requests.get(base_url.format(page_num))
    return bs4.BeautifulSoup(res.text, 'lxml')

page_num = 1
page_count = 20
base_url = 'https://books.toscrape.com/catalogue/page-{}.html'
book_list = []
while page_count * page_num <= 100:
    
    soup = soup_request(page_num, base_url)
    books = soup.select('.product_pod')
    for book in books:
        rating = book.p['class'][1]
        if rating == 'Two':
        title = book.h3.a['title']
            # Not interested in expanding this into a class wrapper or functions at this point. Just getting familiar with the Beautiful Soup obj.
            # So, below - is what I was asking about here. Easiest solution to build a list then unpack the tuples below. 
            book_list.append((title, rating))
    page_num += 1

# Unpack the list.
for x,y in book_list:
    print(x, y)
(Sep-09-2021, 06:39 AM)deanhystad Wrote: From the responses I don't think anyone understands the original request,

Thanks for all of your time.
Matt
This is basically what I was looking to do with a dictionary. I just didn't want to have to refer to each value by key because the key is a value and so is the value - of course.

(Sep-08-2021, 07:52 PM)perfringo Wrote: There are lot of ambiguity for me, so just some examples of dict and EAFP:

>>> ratings = {'Peppa the Pig': 5}
>>> ratings.update([('Bob the Builder', 10)])
>>> ratings
{'Peppa the Pig': 5, 'Bob the Builder': 10}
>>> try:
...     print(ratings['Fireman Sam'])
... except KeyError:
...     print('No rating for this movie')
...
No rating for this movie

So, I ended up with something like this. I'm not sure if it will be the same solution as the instructor's. I'm sure there a several different ways to do this.

import requests
import bs4

def soup_request(page_num, base_url):
    res = requests.get(base_url.format(page_num))
    return bs4.BeautifulSoup(res.text, 'lxml')

page_num = 1
page_count = 20
base_url = 'https://books.toscrape.com/catalogue/page-{}.html'
book_list = []

while page_count * page_num <= 1000:
    
    soup = soup_request(page_num, base_url)
    books = soup.select('.product_pod')
    for book in books:
        rating = book.p['class'][1]
        if rating == 'Two':
            title = book.h3.a['title']
            book_list.append((title, rating))
            
    page_num += 1

for title, rating in book_list:
    print(f'Title: {title}, Rating: {rating}')

This would definitely be the next step if I decided to harvest the data. I would probably build a wrapper class, the create instances of one of the many ORMs out there.

I'm assuming, dataset is a SQL package? I am between beginner and intermediate with Python. I was a web developer up until 15 years ago. I started in the 90's with something called Cold Fusion and ASP. Then, vb.net, C#. I decided that I hate Microsoft when I was forced to pay for third party controls to use in my code. The reason I stopped is a long story. But now I want to use Python and Linux.

(Sep-09-2021, 12:54 AM)snippsat Wrote: Have to structure it different to make some sense.
A basic example with a nested dictionary.
>>> from pprint import pprint
>>>
>>> movies = {'movie1': {'Title': 'Rocky', 'Rating': 5}, 'movie2': {'Title': 'Rocky3', 'Rating': 4}}
>>>
>>> # Add
>>> movies['movie3'] = {'Title': 'First blood', 'Rating': 6}
>>> pprint(movies)
{'movie1': {'Rating': 5, 'Title': 'Rocky'},
 'movie2': {'Rating': 4, 'Title': 'Rocky3'},
 'movie3': {'Rating': 6, 'Title': 'First blood'}}

>>> # Search
>>> find_movie = 'First blood'
>>> for movie_id, movie_info in movies.items():
...     if find_movie in movie_info['Title']:
...         print(movie_info)
{'Title': 'First blood', 'Rating': 6}

>>> for movie_id, movie_info in movies.items():
...     if 'First blood' in movie_info['Title']:
...         print(f"Found <{movie_info.get('Title')}> with a rating of <{movie_info.get('Rating')}>")
Found <First blood> with a rating of <6>

Database can come to mind when doing this,a demo of a easy way with dataset.
import dataset

movies = [
    {'Title': 'Rocky', 'Rating': 5},
    {'Title': 'Rocky3', 'Rating': 4},
    {'Title': 'First blood', 'Rating': 6}
]

db = dataset.connect('sqlite:///movies.db')
table = db['movie_table']
for movie in movies:
    table.insert(movie)
>>> [m for m in db['movie_table']]
[OrderedDict([('id', 1), ('Title', 'Rocky'), ('Rating', 5)]),
 OrderedDict([('id', 2), ('Title', 'Rocky3'), ('Rating', 4)]),
 OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)])]
>>> 
>>> table.find_one(Title='First blood')
OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)])
>>> 
>>> # Have now also SQL queries
>>> [m for m in db.query("select * from movie_table order by Rating desc limit 3")]
[OrderedDict([('id', 3), ('Title', 'First blood'), ('Rating', 6)]),
 OrderedDict([('id', 1), ('Title', 'Rocky'), ('Rating', 5)]),
 OrderedDict([('id', 2), ('Title', 'Rocky3'), ('Rating', 4)])]
Reply
#10
(Sep-09-2021, 12:40 PM)muzikman Wrote: I'm assuming, dataset is a SQL package?
It's been built on top of SQLAlchemy, so then will dataset works with all major databases, such as SQLite, PostgreSQL and MySQL.
The advantage is of course the simple usage,so it's good for smaller project.

Can use your code as example with some modification to make database using build in sqlite3 .
import requests
import bs4
import dataset

def soup_request(page_num, base_url):
    res = requests.get(base_url.format(page_num))
    return bs4.BeautifulSoup(res.content, 'lxml')

page_num = 1
page_count = 20
base_url = 'https://books.toscrape.com/catalogue/page-{}.html'
book_list = []
while page_count * page_num <= 1000:
    soup = soup_request(page_num, base_url)
    books = soup.select('.product_pod')
    for book in books:
        rating = book.p['class'][1]
        title = book.h3.a['title']
        book_list.append((('Title', title), ('Rating',rating)))
    page_num += 1

# To DB
books = []
for book in book_list:
    books.append(dict((y, x) for y, x in book))
db = dataset.connect('sqlite:///books.db')
table = db['book_table']
for book_info in books:
    table.insert(book_info)
So not much code and now have fully functional database
Usage test.
>>> Sapiens = table.find_one(Title='Sapiens: A Brief History of Humankind')
>>> Sapiens
OrderedDict([('id', 5),
             ('Title', 'Sapiens: A Brief History of Humankind'),
             ('Rating', 'Five')])
>>> Sapiens.get('Rating')
'Five'
Have also full power of SQL queries,so how many books has History in Title.
>>> [b for b in db.query("SELECT * from book_table WHERE (lower(title) LIKE '%History%');")]
[OrderedDict([('id', 5),
              ('Title', 'Sapiens: A Brief History of Humankind'),
              ('Rating', 'Five')]),
 OrderedDict([('id', 60),
              ('Title',
               'The Natural History of Us (The Fine Art of Pretending #2)'),
              ('Rating', 'Three')]),
 OrderedDict([('id', 134),
              ('Title',
               'Thomas Jefferson and the Tripoli Pirates: The Forgotten War '
               'That Changed American History'),
              ('Rating', 'One')]),
 OrderedDict([('id', 147),
              ('Title',
               "The Omnivore's Dilemma: A Natural History of Four Meals"),
              ('Rating', 'Two')]),
 OrderedDict([('id', 303),
              ('Title', 'Greek Mythic History'),
              ('Rating', 'Five')]),
 OrderedDict([('id', 347),
              ('Title', "A People's History of the United States"),
              ('Rating', 'Two')]),
 OrderedDict([('id', 464),
              ('Title', 'Please Kill Me: The Uncensored Oral History of Punk'),
              ('Rating', 'Four')]),
 OrderedDict([('id', 480), ('Title', 'History of Beauty'), ('Rating', 'Four')]),
 OrderedDict([('id', 486),
              ('Title',
               'Brilliant Beacons: A History of the American Lighthouse'),
              ('Rating', 'Three')]),
 OrderedDict([('id', 544),
              ('Title', 'A Short History of Nearly Everything'),
              ('Rating', 'Five')]),
 OrderedDict([('id', 547),
              ('Title',
               'The Rise and Fall of the Third Reich: A History of Nazi '
               'Germany'),
              ('Rating', 'Two')]),
 OrderedDict([('id', 640),
              ('Title',
               "America's War for the Greater Middle East: A Military History"),
              ('Rating', 'Two')]),
 OrderedDict([('id', 691),
              ('Title',
               'A History of God: The 4,000-Year Quest of Judaism, '
               'Christianity, and Islam'),
              ('Rating', 'One')]),
 OrderedDict([('id', 693),
              ('Title', 'Zero History (Blue Ant #3)'),
              ('Rating', 'One')]),
 OrderedDict([('id', 695),
              ('Title', 'World War Z: An Oral History of the Zombie War'),
              ('Rating', 'One')]),
 OrderedDict([('id', 757),
              ('Title',
               'The Disappearing Spoon: And Other True Tales of Madness, Love, '
               'and the History of the World from the Periodic Table of the '
               'Elements'),
              ('Rating', 'Five')])]
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  ValueError: Length mismatch: Expected axis has 8 elements, new values have 1 elements ilknurg 1 5,013 May-17-2022, 11:38 AM
Last Post: Larz60+
  Sorting Elements via parameters pointing to those elements. rpalmer 3 2,550 Feb-10-2021, 04:53 PM
Last Post: rpalmer
  Looping through dictionary and comparing values with elements of a separate list. Mr_Keystrokes 5 3,834 Jun-22-2018, 03:08 PM
Last Post: wavic

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020