2015-05-01 42 views
1

我試圖創建一個字典,其中的關鍵是日期,
在我的情況下,每個日期是這樣的列表:[2012, 5, 25]Python添加列表作爲字典中的鍵

這是我從csv文件讀入字典的代碼。
此代碼給我不能改變它:

def read_profiles(r_file_name): 
    """Reads the file profiles-full.csv into a dictionary where the key is the users id 
    and the value is a dictionary with users fields "public", "compl_percent", "gender", 
    "region", "last_login", "age", "body". In addition to this dictionary, the function 
    returns the list of all users that have 0 completion percentage.""" 
    users = {} 
    noinfo_users = [] 
    with open(r_file_name, 'rb') as csvfile: 
     linereader = csv.reader(csvfile) 
     for line in linereader: 
      profile = {} 
      data_fields = ("public", "compl_percent", "gender", "region", 
            "last_login", "age", "body") 
      for field, raw_data in zip(data_fields, line[1:]): 
       if field == "compl_percent" and int(raw_data) == 0: 
        noinfo_users.append(int(line[0])) 

       if raw_data == "null": 
        profile[field] = None 
       elif field == "body": 
        profile[field] = raw_data 
       elif field == "last_login": #<=== reading last_login 
        profile[field] = map(int, raw_data.split("-")) 
       elif field == "region": 
        profile[field] = map(int, raw_data.split(";")) 
       else: 
        profile[field] = int(raw_data) 

      users[int(line[0])] = profile 
    return users, noinfo_users 

這是CSV文件的內容,與此對應的模式:

"public", "compl_percent", "gender", "region",     "last_login", "age", "body"** 
231702, 1, 60, 0, 1;1;21, 2012-05-15, 0, 171 cm;58 kg 

這是怎麼在配置文件中的字典元素看起來像:

1492433: {'body': '160 cm;54 kg', 'compl_percent': 78, 'gender': 0, 'region': [1, 10, 6], 'age': 36, 'last_login': [2012, 5, 25], 'public': 1} 

這是我的函數:

def getStrongConnectedForAttr(user,edges,profiles,attr): 
    result = dict() 
    if user in edges: 
     userFriends = edges.get(user) 
     for friend in userFriends: 
      if isBidirectional(edges,user,friend) == 2: 
       if friend in profiles: 
        friendAttr = (profiles.get(friend))[str(attr)] 
        if attr == "last_login": 
         #friendAttr = '-'.join(map(str, friendAttr)) 
         friendAttr = tuple(friendAttr) 
        if friendAttr in result: #<===== error 
         result[friendAttr] = result.get(friendAttr) + 1 
        else: 
         result[friendAttr] = 1 
     return sorted(result.items(), key=operator.itemgetter(1), reverse=True) 
    else: 
     return result 

它將配置文件作爲參數之一,並構建一個空字典。
在行if friendAttr in result:我得到的錯誤:

TypeError: unhashable type: 'list' 

我試圖尋找解決方案的網絡,我發現有很多,特別是在這裏對堆棧溢出,並且你可以看到我嘗試了許多解決方案,一個轉換的列表到元組,或將列表連接到字符串。
但他們都沒有工作。

+0

只是轉換爲一個元組:'元組(friendAttr)' –

+2

將你的鑰匙插入一個元組肯定應該有工作;但爲什麼你這樣做*有條件*? –

+0

正如消息所說,字典中的一個關鍵字必須是可散列的(https://docs.python.org/2/glossary.html#term-hashable) - 既然它是一個日期,你可以將它字符串化並存儲它作爲關鍵。 – karthikr

回答

1

您只是將login_attr值轉換爲元組,但忘記了region屬性。這是那些仍然拋出異常的值。

您只是在測試的login_attr這裏:

if attr == "last_login": 
    friendAttr = tuple(friendAttr) 

而不是讀文件時把你的價值觀元組那裏,只是店的元組

更換

elif field == "last_login": #<=== reading last_login 
    profile[field] = map(int, raw_data.split("-")) 
elif field == "region": 
    profile[field] = map(int, raw_data.split(";")) 

elif field == "last_login": 
    profile[field] = tuple(map(int, raw_data.split("-"))) 
elif field == "region": 
    profile[field] = tuple(map(int, raw_data.split(";"))) 
+0

,即使我的密鑰是一個數字,它也能工作嗎?因爲正如你可以在配置文件元素中看到的,我有各種各樣的東西,列表,數字...... – Epsilon

+0

@Epsilon:對,你總是可以*先測試列表,或者不首先存儲列表。 –

+0

@Epsilon:用更好的方法更新;把你的值先變成*元組,並處理兩者。 –