在字典中查找联合和交集

时间:2014-11-09 20:48:51

标签: python dictionary

我有一本字典,里面有电影中的电影和演员列表,我试图写两个函数:一个在任何两个电影中找到所有演员,另一个在两个电影中只找到演员。电影。这就是我所拥有的:

def allActors(movie1,movie2):
    dictionary1=makeDictionaryFromFile()
    actor1=[]
    actor2=[]
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        actor1=dictionary1[movie1]
        actor2=dictionary1[movie2]
        return actor1+actor2

def actorsOverlap(movie1,movie2):
    dictionary1=makeDictionaryFromFile()
    actor1=[]
    actor2=[]
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        actor1=dictionary1[movie1]
        actor2=dictionary1[movie2]
        actors=[]
        for name in actor1:
            if name in actor2:
                actors=actors.append([name])
                return actors

字典看起来像这样:

{'Harry Potter': ['Daniel Radcliffe', 'Emma Thompson', 'Alan Rickman'], 'Sense and Sensibility': ['Emma Thompson', 'Alan Rickman', 'Hugh Grant']}

所以第一个应该给:

['Daniel Radcliffe', 'Emma Thompson', 'Alan Rickman','Emma Thompson', 'Alan Rickman', 'Hugh Grant']

(我还没弄明白如何让艾玛·汤普森和艾伦·里克曼“只打印一次”

第二个应该给出:

['Emma Thompson', 'Alan Rickman']

这是一个较长项目的一部分,到目前为止看起来像这样(有建议的编辑):

from Myro import *
def makeDictionaryFromFile():
   dictionary1={}
   try:
       infile = open("films.txt","r")
       nextLineFromFile = infile.readline().rstrip('\r\n')
       while (nextLineFromFile != ""):
            line = nextLineFromFile.split(",")
            first=line[0]
            dictionary1[first]=line[1:]
            nextLineFromFile = infile.readline().rstrip('\r\n')
    except:
        print ("File not found! (or other error!)")
    return dictionary1

def makeReverseDictionary():
    dictionary1 ={}
    dictionary1 = makeDictionaryFromFile()
    dictionary2 = {}
    for k,vlist in dictionary1.iteritems():
        for v in vlist:
            dictionary2.setdefault(v,[]).append(k)
    return dictionary2

 def allActors(movie1,movie2):
    dictionary1 = makeDictionaryFromFile()
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return list(set(dictionary1[movie1]+ dictionary1[movie2]))
    return None

def actorsOverlap(movie1,movie2):
    dictionary1 = makeDictionaryFromFile()
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return list(set(dictionar1.values) & set(dictionary2.values()))

def coactors(actor):
    dictionary2 = makeDictionaryFromFile()
    (some code)

def menu():
    answer=askQuestion("choose one",["create actor-title dictionary", "create title-actor dictionary", "find all actors in two movies", "find all overlapping actors in two movies","find all actors not in both movies","find all co-actors of an actor","Nothing, I wish to quit"])
    if answer == ("create actor-title dictionary"):
        answer = 1
    elif answer == ("create title-actor dictionary"):
        answer = 2
    elif answer == ("find all actors in two movies"):
        answer = 3
    elif (answer == "find all overlapping actors in two movies"):
        answer = 4
    elif (answer == "find all co-actors of an actor"):
        answer = 5
    elif (answer == "Nothing, I wish to quit"):
        answer = 6
    return answer

def main():
    choice = menu()
    while (choice != 6):
        if (choice == 1):
            dictionary=makeDictionaryFromFile()
            print (dictionary)
        elif (choice == 2):
            dictionary=makeReverseDictionary()
            print (dictionary)
        elif (choice == 3):
            movie1=input("first movie")
            movie2=input("second movie")
            actors=allActors(movie1, movie2)
            print (actors)
        elif (choice == 4):
            movie1=input("first movie")
            movie2=input("second movie")
            actors=actorsOverlap(movie1,movie2)
            print (actors)
        elif (choice == 5):
            actor=input("actor's name")
            try:
                coactors=coactors(actor)
                print (coactors)
            except:
                 print ("Error. Check spelling and try again.")
        choice = menu()

4 个答案:

答案 0 :(得分:1)

您可以使用set

根据定义,集合仅包含唯一元素。

以下是使用集合的代码的粗略重写(假设字典仍然保存列表):

def allActors(movie1,movie2):
    dictionary1=makeDictionaryFromFile()
    actor1 = set(dictionary1.get(movie1, []))
    actor2 = set(dictionary1.get(movie2, []))
    return actor1.union(actor2)

def actorsOverlap(movie1,movie2):
    dictionary1=makeDictionaryFromFile()
    actor1 = set(dictionary1.get(movie1, []))
    actor2 = set(dictionary1.get(movie2, []))
    return actor1.intersection(actor2)

答案 1 :(得分:1)

您可以使用reduceset查找值和互动的并集

d={'Harry Potter': ['Daniel Radcliffe', 'Emma Thompson', 'Alan Rickman'], 'Sense and Sensibility': ['Emma Thompson', 'Alan Rickman', 'Hugh Grant']}

union= reduce(lambda x,y:x+y, d.values())
inter= reduce(lambda x,y:list(set(x) & set(y)), d.values())
print inter, union

输出:

['Emma Thompson', 'Alan Rickman'] 
['Daniel Radcliffe', 'Emma Thompson', 'Alan Rickman', 'Emma Thompson', 'Alan Rickman', 'Hugh Grant']

答案 2 :(得分:0)

我会按如下方式重写您的功能:

def allActors(movie1, movie2):
    dictionary1 = makeDictionaryFromFile()
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return set(dictionary1[movie1] + dictionary1[movie2])
    return None

def actorsOverlap(movie1,movie2):
    dictionary1 = makeDictionaryFromFile()
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return set(dictionary1[movie1]).intersection(set(dictionary1[movie2]))
    return set()

答案 3 :(得分:0)

dictionary1=makeDictionaryFromFile() # make dictionary1 one time , it will be availabe for all function
def allActors(movie1,movie2):
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return list(set(dictionary1[movie1]+ dictionary1[movie2]))

def actorsOverlap(movie1,movie2):
    if movie1 in dictionary1.keys() and movie2 in dictionary1.keys():
        return list(set(dictionar1[movie1]) & set(dictionary2[movie2]))

set生成无序的唯一列表

set1 & set 2将为您提供所有常用元素,无需创建额外的actor1和actor2列表。