2013-04-15 41 views
0

我有一個文本文件,數以十萬計的學生,他們對某些電影的評級,第一個詞是學生號碼,第二個是電影名稱(與沒有空格),第三是評級,他們給了這部電影:維護電影/等級的大列表中的秩序

student1000 Thor 1 
student1001 Superbad -3 
student1002 Prince_of_Persia:_The_Sands_of_Time 5 
student1003 Old_School 3 
student1004 Inception 5 
student1005 Finding_Nemo 3 
student1006 Tangled 5 

我想這樣,我每個學生映射到他們的電影分級制度,其中收視率是他們在字典中安排按每個學生的順序排列。換句話說,我想有這樣的:

{student1000 : [1, 3, -5, 0, 0, 3, 0,...]} 
{student1001 : [0, 1, 0, 0, -3, 0, 1,...]} 

使得第一,第二,第三等爲每個學生等級對應於相同的電影。這個順序對於電影和學生號碼是完全隨機的,而且我很難有效地做到這一點。任何幫助提出一些可以最大限度地減少這個問題的大O複雜性的東西將會非常棒。

我終於搞清楚了。這裏是我用於任何人想知道的代碼:

def get_movie_data(fileLoc): 
    movieDic = {} 
    movieList = set() 

    f = open(fileLoc) 
    setHold = set() 
    for line in f: 
     setHold.add(line.split()[1]) 
    f.close() 
    movieList = sorted(setHold) 

    f = open(fileLoc) 
    for line in f: 
     hold = line.strip().split() 
     student = hold[0] 
     movie = hold[1] 
     rating = int(hold[2]) 
     if student not in movieDic: 
      lst = [0]*len(movieList) 
      movieDic[student] = lst 
     hold2 = movieList.index(movie) 
     rate = movieDic[student] 
     rate[hold2] = rating 
    f.close() 
    return movieList, movieDic 

感謝您的幫助!

回答

2

可以先建詞典的詞典:

{ 
'student1000' : {'Thor': 1, 'Superbad': 3, ...}, 
'student1001' : {'Thor': 0, 'Superbad': 1, ...}, 
... 
} 

然後你可以通過讓所有的電影的主列表,爲他們建立一個順序(每個學生的評價中對應的順序列表),最後遍歷字典中的每個學生,將字典轉換爲您想要的列表。或者,像另一個答案說的那樣,只要把它作爲一本字典。

defaultdict可能會派上用場。它可以讓你說,每個學生的默認值是一個空的列表(或字典),所以你不必在開始附加值(或設置鍵值對)之前對它進行初始化。

from collections import defaultdict 

students = defaultdict(dict) 
with open(filename, 'r') as f: 
    for line in f.readlines(): 
     elts = line.split() 
     student = elts[0] 
     movie = elts[1] 
     rating = int(elts[2]) 
     students[student][movie] = rating 
0

只需將分數放入字典而不是列表中。讀完所有數據後,您可以提取電影名稱並按照您想要的順序放入。假設學生可以對不同的電影進行評分,在閱讀文件時保持某種一致的順序,而不知道電影的開頭順序,似乎很多工作。

如果您擔心密鑰佔用大量內存,請在密鑰上使用intern()以確保您只存儲每個字符串的一個副本。

1

所以,這裏的答案是功能上與你彷彿在尋找,但是就直接構建你要找的名單,他們似乎是在回答略微不同的問題。就我個人而言,我寧願以更動態的方式做到這一點。因爲在我看來,你並不知道你實際上知道將要被提前評分的電影,所以你必須保持某種運行狀態。

ratings = {} 
allMovies = [] 
    for line in file: 
     info = line.split(" ") 
     movie = info[1].strip().lower() 
     student = info[0].strip().lower() 
     rating = float(info[2].strip().lower()) 
     if movie not in allMovies: 
      allMovies.append(movie) 
     movieIndex = allMovies.index(movie) 
     if student not in ratings: 
      ratings[student] = ([0]*(len(allMovies)-1)).append(rating) 
     else: 
      if len(allMovies) > len(ratings[student]): 
       ratings[student] = ratings[student].extend([0]*(len(allMovies)-len(ratings[student])) 
      ratings[student][movieIndex] = rating 

這不是我想解決這個問題的方式,但我認爲這個解決方案是最接近問題的原意,你可以使用一個緩衝區中的行養活,如果有一個內存問題,但除非你的文件是幾千兆字節,應該不會有問題。

+0

這看起來像是我在找的東西。但是,當我嘗試獲取長度時,變量「ratings [student]」會給出錯誤,因爲它是Nonetype。我對Python類型並不十分熟悉,但是我怎麼讓計算機知道它是一個列表? – weskpga

+0

如果你只是說評級[學生] = []它應該讓Python知道這是一個列表。它應該在學生不在評分的循環中實例化列表。您能否深入瞭解一下您的確切錯誤和實施情況? –

+0

我想通了,如我的編輯。謝謝您的幫助! – weskpga