简体   繁体   中英

Read csv file, parse data, and store in a dictionary

I have a file that contains songs recently played by a radio station, the artist, and time played in this format: "November 4, 2019 8:02 PM","Wagon Wheel","Darius Rucker". I am trying to store the content of this file in string variable playlist_csv, use splitlines() to store records in variable lines, and then iterate through the lines to store data in a dictionary. The key should be a datetime object of the timestamp, and the value should be a tuple of song and artist: {datetime_key: (song, artist)}

Here's an excerpt from the file:

"November 4, 2019 8:02 PM","Wagon Wheel","Darius Rucker" 
"November 4, 2019 7:59 PM","Remember You Young","Thomas Rhett" 
"November 4, 2019 7:55 PM","Long Hot Summer","Keith Urban" 

This is what the desired dictionary should look like:

{datetime.datetime(2019, 11, 4, 20, 2): ('Wagon Wheel', 'Darius Rucker'), 
datetime.datetime(2019, 11, 4, 19, 59): ('Remember You Young', 'Thomas Rhett'), 
datetime.datetime(2019, 11, 4, 19, 55): ('Long Hot Summer', 'Keith Urban')}

This is what I have for code so far:

# read the file and store content in string variable playlist_csv
with open('playlist.txt', 'r') as csv_file:
    playlist_csv = csv_file.read().replace('\n', '')
    # use splitlines() method to store records in variable lines (it is list)
    split_playlist = playlist_csv.splitlines()
    # iterate through lines to store data in playlist_dict dictionary
    playlist_dict = {}
    for l in csv.reader(split_playlist, quotechar='"', delimiter=',',
       quoting=csv.QUOTE_ALL, skipinitialspace=True):
       dt=datetime.strptime(l[0], '%B %d, %Y %I:%M %p')
       playlist_dict[l[dt]].append(dt)
print(playlist_dict)

However, I keep running into errors when trying to store this data in a dictionary (specifically "'datetime.datetime' object is not subscriptable" and "list indices must be integers or slices" when modifying the code).

I appreciate any help!

Your attempts to split up the csv file first seem to be unnecessary - the csv.reader takes care of all that for you. And rather than playlist_dict[l[dt]].append(dt) you need something like playlist_dict[dt].append((song, artist)) . This should work:

with open('playlist.txt', 'r') as csv_file:
    playlist = {}
    for time, song, artist in csv.reader(csv_file):
        time = datetime.strptime(time, '%B %d, %Y %I:%M %p')
        if time in playlist:
            playlist[time].append((song, artist))
        else:
            playlist[time] = [(song, artist)]

(The optional arguments you supplied to csv.reader are probably also not needed - the defaults should work for the type of input you have given.)

Or if you only have one possible song/artist at each date-time then you don't need a list and can do this (which seems to be the output you are looking for):

with open('playlist.txt', 'r') as f:
    playlist = {datetime.strptime(time, '%B %d, %Y %I:%M %p'): (song, artist) 
                for time, song, artist in csv.reader(f)}

Since it turns out it may be a better choice for this situation, here is a solution using Pandas. As a bonus, it calculates the time between each song.

import pandas as pd

df = pd.read_csv('../resources/radio_songs.csv', dtype={'song_name': str, 'artist': str},
                 parse_dates=[0], header=None, names=['time_played', 'song_name', 'artist'])

df['time_diff'] = df['time_played'].diff(periods=-1)

The DataFrame output:

          time_played           song_name         artist time_diff
0 2019-11-04 20:02:00         Wagon Wheel  Darius Rucker  00:03:00
1 2019-11-04 19:59:00  Remember You Young   Thomas Rhett  00:04:00
2 2019-11-04 19:55:00     Long Hot Summer    Keith Urban       NaT

If for some reason you ever need it, here is an amusing way recreate that dictionary format:

tuples_dict = dict(zip(df['time_played'], zip(df['song_name'], df['artist'])))

Output:

{Timestamp('2019-11-04 20:02:00'): ('Wagon Wheel', 'Darius Rucker'), Timestamp('2019-11-04 19:59:00'): ('Remember You Young', 'Thomas Rhett'), Timestamp('2019-11-04 19:55:00'): ('Long Hot Summer', 'Keith Urban')}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM