2

学校向けのプログラムを書こうとしています。私はバイオテクノロジー専攻で、これは必須のコースですが、プログラマーではありません。したがって、これはおそらく多くの人にとっては簡単ですが、私にとっては難しいことです。とにかく、約30行のテキストファイルがあります。各行には、最初に映画名が表示され、映画に出演した俳優がカンマで区切られて続きます。これが私がこれまでに持っているものです:

InputName = input('What is the name of the file? ')
File = open(InputName, 'r+').readlines()


ActorLst = []
for line in File:
    MovieActLst = line.split(',')   


    Movie = MovieActLst[0]        
    Actors = MovieActLst[1:]      
    for actor in Actors:
        if actor not in ActorLst:
            ActorLst.append(actor)

    MovieDict = {Movie: Actors for x in MovieActLst} 
    print (MovieDict)
    print(len(MovieDict))

出力 (短縮):

What is the name of the file? Movies.txt
{"Ocean's Eleven": ['George Clooney', 'Brad Pitt', 'Elliot Gould', 'Casey Affleck', 'Carl Reiner', 'Julia Roberts', 'Angie Dickinson', 'Steve Lawrence', 'Wayne Newton\n']}
1
{'Up in the Air': ['George Clooney', 'Sam Elliott', 'Jason Bateman\n']}
1
{'Iron Man': ['Robert Downey Jr', 'Jeff Bridges', 'Gwyneth Paltrow\n']}
1
{'The Big Lebowski': ['Jeff Bridges', 'John Goodman', 'Julianne Moore', 'Sam Elliott\n']}
1

MovieDictキーの映画名と値の俳優のリストを含む辞書 ( ) を作成しました。約30の映画名(キー)があります。このディクショナリを反復して本質的に元に戻す方法を理解する必要があります。俳優をキーとして、俳優が出演する映画を値として含む辞書が必要です。

しかし、私は 1 つの辞書ではなく、辞書のリストも作成したと思います。今では本当に混乱しています。助言がありますか?

4

5 に答える 5

5

を使用して簡単collections.defaultdict:

from collections import defaultdict
reverse = defaultdict(list)

for movie, actors in MovieDict.items():
    for actor in actors:
        reverse[actor].append(movie)

このdefaultdictクラスは、dict存在しないキーにアクセスしようとすると、それを作成し、コンストラクターに渡されたファクトリによって作成されたアイテムにその値を設定するため (list上記のコード)、これにより、のキャッチKeyErrorまたはチェックが回避されます。キーは辞書にあります。

これを Steven Rumbalski のループに入れると、次のようになります。

from collections import defaultdict
in_fname = input('What is the name of the file? ')
in_file = open(in_fname, 'r+')

movie_to_actors = {}
actors_to_movie = defaultdict(list)

for line in in_file:
    #assumes python3:
    movie, *actors = line.strip().split(',')
    #python2 you can do actors=line.strip().split(',');movie=actors.pop(0)

    movie_to_actors[movie] = list(actors)
    for actor in actors:
        actors_to_movie[actor].append(movie)

上記のコードに関するいくつかの説明。

ファイルの行を繰り返す

ファイルオブジェクトは反復可能であるため、反復をサポートします。これは、次のことができることを意味します。

for line in open('filename'):

それ以外の:

for line in open('filename').readlines():

(また、python2では、後者はすべてのファイルを読み取ってからコンテンツを分割しますが、ファイルを反復処理してもすべてのファイルがメモリに読み込まれるわけではありません[したがって、大きなファイルで多くのRAMを節約できます])。

タプルのアンパック

シーケンスを異なる変数に「アンパック」するには、「タプル アンパック」構文を使用できます。

>>> a,b = (0,1)
>>> a
0
>>> b
1

構文が拡張され、可変数の値を 1 つの変数に収集できるようになりました。例えば:

>>> head, *tail = (1, 2, 3, 4, 5)
>>> head
1
>>> tail
[2, 3, 4, 5]
>>> first, *mid, last = (0, 1, 2, 3, 4, 5)
>>> first
0
>>> mid
[1, 2, 3, 4]
>>> last
5

「スター付き式」は 1 つしか持てないため、これは機能しません。

>>> first, *mid, center, *mid2, last  =(0,1,2,3,4,5)
  File "<stdin>", line 1
SyntaxError: two starred expressions in assignment

したがって、基本的に左側に星がある場合、python は他の変数に入れることができなかったすべてのものをそこに入れます。これは、変数が空のリストを参照する可能性があることを意味することに注意してください。

>>> first, *mid, last = (0,1)
>>> first
0
>>> mid
[]
>>> last
1

defaultdict の使用

を使用defaultdictすると、存在しないキーにデフォルト値を与えることができます。このクラスは呼び出し可能 (~関数またはクラス) をパラメーターとして受け入れ、それを呼び出して、必要になるたびにデフォルト値を作成します。

>>> def factory():
...     print("Called!")
...     return None
... 
>>> mydict = defaultdict(factory)
>>> mydict['test']
Called!
于 2012-10-27T16:34:58.393 に答える
1
reverse={}
keys=MovieDict.keys()
for key in keys:
    val=MovieDict[key]
    for actor in val:
        try:
            reverse[actor]=reverse[actor].append(actor)
        except KeyError:
            reverse[actor]=[]
            reverse[actor]=reverse[actor].append(actor)
print(reverse)#retarded python 3 format! :)

それはそれをする必要があります。

于 2012-10-27T15:50:23.530 に答える
1
InputName = input('What is the name of the file? ')
with open(InputName, 'r') as f:
    actors_by_movie = {}
    movies_by_actor = {}
    for line in f:
        movie, *actors = line.strip().split(',')
        actors_by_movie[movie] = actors
        for actor in actors:
            movies_by_actor.setdefault(actor, []).append(movie)
于 2012-10-27T16:27:23.117 に答える
1

プログラミングは物事を抽象化することなので、特定の問題に依存しない方法でコードを書くようにしてください。例えば:

def csv_to_dict(seq, separator=','):
    dct = {}
    for item in seq:
        data = [x.strip() for x in item.split(separator)]
        if len(data) > 1:
            dct[data[0]] = data[1:]
    return dct

def flip_dict(dct):
    rev = {}
    for key, vals in dct.items():
        for val in vals:
            if val not in rev:
                rev[val] = []
            rev[val].append(key)
    return rev

これらの 2 つの関数は、「入力ファイル」、「アクター」、「ムービー」などについて何も「認識」していませんが、2 行のコードで問題を解決できることに注意してください。

with open("movies.txt") as fp:
    print(flip_dict(csv_to_dict(fp)))
于 2012-10-27T17:09:29.427 に答える
0

命名規則に従って:

from collections import defaultdict

InputName = input('What is the name of the file? ')
File = open(InputName, 'rt').readlines()

ActorLst = []
ActMovieDct = defaultdict(list)
for line in File:
    MovieActLst = line.strip().split(',')
    Movie = MovieActLst[0]
    Actors = MovieActLst[1:]
    for actor in Actors:
        ActMovieDct[actor].append(Movie)

# print results    
for actor, movies in ActMovieDct.items():
    print(actor, movies)
于 2012-10-27T17:10:01.910 に答える