2017-01-29 4 views
1

Ich habe zwei Dateien Ich möchte eine spezifische Leistung vergleichen und dann produzieren:zwei Listen vergleichen und von einem Feld suchen, Python

1) Im Folgenden wird der Inhalt der Benutzertextdatei ist (dies die neuesten Filme speichert angesehen durch den Benutzer)

Sci-Fi,Out of the Silent Planet 
    Sci-Fi,Solaris 
    Romance, When Harry met Sally 

2) im Folgenden sind die Inhalte der films.txt Datei, die alle Filme im Programm speichert, die

0,Genre, Title, Rating, Likes 
1,Sci-Fi,Out of the Silent Planet, PG,3 
2,Sci-Fi,Solaris, PG,0 
3,Sci-Fi,Star Trek, PG,0 
4,Sci-Fi,Cosmos, PG,0 
5,Drama, The English Patient, 15,0 
6,Drama, Benhur, PG,0 
7,Drama, The Pursuit of Happiness, 12, 0 
8,Drama, The Thin Red Line, 18,0 
9,Romance, When Harry met Sally, 12, 0 
10,Romance, You've got mail, 12, 0 
11,Romance, Last Tango in Paris, 18, 0 
12,Romance, Casablanca, 12, 0 

Ein Beispiel th für den Benutzer verfügbar sind Die Ausgabe, die ich benötige: Der Benutzer hat gerade zwei Sci-Fi und einen Romance Film angeschaut. Die Ausgabe sollte daher die Filmtextdatei nach Genre suchen (SCI-FI und ROMANCE identifizieren) und sollte die Filme in der films.txt-Datei auflisten, die noch NICHT vom Benutzer angesehen wurden. In diesem Fall

3,Sci-Fi,Star Trek, PG,0 
4,Sci-Fi,Cosmos, PG,0 
10,Romance, You've got mail, 12, 0 
11,Romance, Last Tango in Paris, 18, 0 
12,Romance, Casablanca, 12, 0 

Ich habe den folgenden Code, der die oben genannten zu tun versucht, aber die Ausgabe, die es erzeugt, ist falsch:

def viewrecs(username): 
    #set the username variable to the text file -to use it in the next bit 
    username = (username + ".txt") 
    #open the username file that stores latest viewings 
    with open(username,"r") as f: 
     #open the csv file reader for the username file 
      fReader=csv.reader(f) 
      #for each row in the fReader 
      for row in fReader: 
      #set the genre variable to the row[0], in which row[0] is all the genres (column 1 in username file) 
      genre=row[0] 
      #next, open the films file 
      with open("films.txt","r") as films: 
       #open the csv reader for this file (filmsReader as opposed to fReader) 
       filmsReader=csv.reader(films) 
       #for each row in the films file 
       for row in filmsReader: 
        #and for each field in the row 
        for field in row: 
         #print(field) 
         #print(genre) 
         #print(field[0]) 
         if genre in field and row[2] not in fReader: 
         print(row) 

Ausgang (unerwünschte):

['1', 'Sci-Fi', 'Out of the Silent Planet', ' PG', '3'] 
['2', 'Sci-Fi', 'Solaris', ' PG', '0'] 
['3', 'Sci-Fi', 'Star Trek', ' PG', '0'] 
['4', 'Sci-Fi', 'Cosmos', ' PG', '0'] 

I Ich möchte keine Umschreibung oder neue Lösung, aber vorzugsweise eine Lösung für die obige Lösung mit ihrem logischen Verlauf ...

@gipsy - Ihre Lösung scheint fast zu funktionieren. Früher habe ich:

def viewrecs(username): 

    #set the username variable to the text file -to use it in the next bit 
    username = (username + ".txt") 
    #open the username file that stores latest viewings 
    lookup_set = set() 
    with open(username,"r") as f: 
    #open the csv file reader for the username file 
    fReader=csv.reader(f) 
    #for each row in the fReader 
    for row in fReader: 
     genre = row[1] 
     name = row[2] 
     lookup_set.add('%s-%s' % (genre, name)) 
    with open("films.txt","r") as films: 
    filmsReader=csv.reader(films) 
    #for each row in the films file 
    for row in filmsReader: 
     genre = row[1] 
     name = row[2] 
     lookup_key = '%s-%s' % (genre, name) 
     if lookup_key not in lookup_set: 
     print(row) 

Die Ausgabe ist wie folgt: Es druckt alle Linien in allfilms, die nicht in der ersten Gruppe ist, und nicht nur die, die im ersten Satz auf das GENRE basierte:

['0', 'Genre', ' Title', ' Rating', ' Likes'] 
['3', 'Sci-Fi', 'Star Trek', ' PG', ' 0'] 
['4', 'Sci-Fi', 'Cosmos', ' PG', ' 0'] 
['5', 'Drama', ' The English Patient', ' 15', ' 0'] 
['6', 'Drama', ' Benhur', ' PG', ' 0'] 
['7', 'Drama', ' The Pursuit of Happiness', ' 12', ' 0'] 
['8', 'Drama', ' The Thin Red Line', ' 18', ' 0'] 
['10', 'Romance', " You've got mail", ' 12', ' 0'] 
['11', 'Romance', ' Last Tango in Paris', ' 18', ' 0'] 
['12', 'Romance', ' Casablanca', ' 12', ' 0'] 

HINWEIS: ich änderte das Format des ersten Satzes gleich sein, der Einfachheit halber, der alle Filme Einträge:

1,Sci-Fi,Out of the Silent Planet, PG 
2,Sci-Fi,Solaris, PG 

Antwort

0

Wie über Sets und separate Listen mit Filmen in geeigneten filtern Genres, die nicht gesehen wurden? Wir können sogar die Wörterbücher missbrauchen keys und values zu diesem Zweck:

def parse_file (file): 
    return map(lambda x: [w.strip() for w in x.split(',')], open(file).read().split('\n')) 

def movies_to_see(): 
    seen = {film[0]: film[1] for film in parse_file('seen.txt')} 
    films = parse_file('films.txt') 
    to_see = [] 

    for film in films: 
     if film[1] in seen.keys() and film[2] not in seen.values(): 
      to_see.append(film) 
    return to_see 
+0

ist to_see in Ihrem Code gemeint um movies_to_see zu sein? –

+0

'movies_to_see' ist die Methode,' to_see' ist das Array, das zurückgegeben wird. – Uriel

+0

Ich bin nicht vertraut mit Lambda und der Verwendung von Karten, also wäre es wiederum sehr hilfreich, jede Zeile zu kommentieren. Ich würde versuchen, aber es ist nicht offensichtlich, wo es und seine Bedeutung zu implementieren ... –

0

Okay, bauen einen Satz durch die erste Datei als Eintrag mit Genre + Name geht.

Jetzt iterieren Sie über die zweite Datei und suchen Sie in dem Satz, den Sie oben für einen Eintrag für Genre + Name erstellt haben, wenn nicht, drucken Sie das aus.

Sobald ich zu Hause bin, kann ich einen Code eingeben.

Wie versprochen mein Code dafür ist unten:

def viewrecs(username): 
    #set the username variable to the text file -to use it in the next bit 
    username = (username + ".txt") 
    # In this set we will collect the unique combinations of genre and name 
    genre_name_lookup_set = set() 
    # In this set we will collect the unique genres 
    genre_lookup_set = set() 
    with open(username,"r") as f: 
    #open the csv file reader for the username file 
    fReader=csv.reader(f) 
    #for each row in the fReader 
    for row in fReader: 
     genre = row[0] 
     name = row[1] 
     # Add the genre name combination to this set, duplicates will be taken care automatically as set won't allow dupes 
     genre_name_lookup_set.add('%s-%s' % (genre, name)) 
     # Add genre to this set 
     genre_lookup_set.add(genre) 
    with open("films.txt","r") as films: 
    filmsReader=csv.reader(films) 
    #for each row in the films file 
    for row in filmsReader: 
     genre = row[1] 
     name = row[2] 
     # Build a lookup key using genre and name, example:Sci-Fi-Solaris 
     lookup_key = '%s-%s' % (genre, name) 
     if lookup_key not in genre_name_lookup_set and genre in genre_lookup_set: 
     print(row) 
+0

Könnten Sie den Code für diese Antwort verständlich machen? Gener = Genre? Vielen Dank –

+0

Entschuldigung für den Tippfehler. Ja. Ich meine Genre. – gipsy

+0

@pythoncarrot Meine Antwort wurde mit Code aktualisiert. Bitte beachten Sie – gipsy

0

Die Lösung mit str.split() und str.join() Funktionen:

# change file paths with your actual ones 
with open('./text_files/user.txt', 'r') as userfile: 
    viewed = userfile.read().split('\n') 
    viewed_genders = set(g.split(',')[0] for g in viewed) 

with open('./text_files/films.txt', 'r') as filmsfile: 
    films = filmsfile.read().split('\n') 
    not_viewed = [f for f in films 
        if f.split(',')[1] in viewed_genders and ','.join(f.split(',')[1:3]) not in viewed] 

print('\n'.join(not_viewed)) 

Der Ausgang:

3,Sci-Fi,Star Trek, PG,0 
4,Sci-Fi,Cosmos, PG,0 
10,Romance, You've got mail, 12, 0 
11,Romance, Last Tango in Paris, 18, 0 
12,Romance, Casablanca, 12, 0 
+0

Sind Sie in der Lage, den Code für jede Zeile zu kommentieren und was er tut - das wäre am hilfreichsten für das Verständnis der Logik. Wenn Sie genau das ausprobieren, was Sie vorgeschlagen haben, tritt der folgende Fehler auf; if f.split (',') [1] in viewed_genres und ','. join (f.split (',') [1: 3]) nicht angezeigt] IndexError: Listenindex außerhalb des Bereichs –

+0

@pythoncarrot , es sollte keine Fehler geben, ich habe es auf die Inhalte getestet, die Sie gepostet haben - es funktioniert gut. Überprüfen Sie Ihren Code auf Fehler und prüfen Sie, ob in einigen Ihrer Dateien zusätzliche Spalten vorhanden sind. – RomanPerekhrest

+0

der Fehler bleibt bestehen: wenn f.split (',') [1] in viewed_genres und ','. Join (f.split (',') [1: 3]) nicht in der Ansicht] IndexError: Listenindex aus Im Bereich –