2014-02-10 58 views
0

我試圖將元組列表(下面的例子z)轉換爲z1。 z中的前2項可以相同,因此將成爲結果字典中的通用字段。請在下面。我的嘗試也被顯示,但它沒有將常用元素分組?任何幫助?python列表的元組到列表的字典嵌套列表

FROM: 

z= [(53, 'example 2', 2, 'instagram', 'nyc'), 
    (53, 'example 2', 5, 'instagram', 'detroit'), 
    (53, 'example 2', 7, 'twitter', 'harlem'), 
    (50, 'example 5', 8, 'twitter', 'harlem'), 
    (27, 'example 6', None, None, None), 
    ] 

TO: 

z1=[ 
{'id':  53, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 2, 'platform': 'instagram', 'tagname': 'nyc' }, 
       { 'tag_id': 5, 'platform': 'instagram', 'tagname': 'detroit' }, 
       { 'tag_id': 7, 'platform': 'twitter', 'tagname': 'harlem' }, 
       ] 
}, 
{'id':  50, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 8, 'platform': 'twitter', 'tagname': 'harlem' }, 
       ] 
}, 
{'id':  27, 
    'name':  'example 6', 
    'hashtags': [ { 'tag_id': None, 'platform': None, 'tagname': None }, 
       ] 
}, 
] 

我嘗試:

ld = [] 
for a, b, c, d, e in z: 
    ld.append({ 'id':  a, 
       'name':  b, 
       'tag_id': c, 
       'hashtags': [{'platform': d, 'hashtag': e}, ] 
      }) 

print ld 

輸出:

[ 
{'id':  53, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 2, 'platform': 'instagram', 'tagname': 'nyc' }] 
}, 
{'id':  53, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 5, 'platform': 'instagram', 'tagname': 'detroit' }] 
}, 
{'id':  53, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 7, 'platform': 'twitter', 'tagname': 'harlem' },] 
}, 
{'id':  50, 
    'name':  'example 2', 
    'hashtags': [ { 'tag_id': 8, 'platform': 'twitter', 'tagname': 'harlem' }, 
       ] 
}, 
{'id':  27, 
    'name':  'example 6', 
    'hashtags': [ { 'tag_id': None, 'platform': None, 'tagname': None }, 
       ] 
}, 
] 
+0

不要忘記標記你最終使用的答案。 – Geoff

回答

3

的問題是,你是不是想看看,如果你已經添加指定id的字典ld(「我已經將ID爲53的元素添加到列表中?」)。你需要檢查你是否已經添加它。

想到的第一件事就是將以前的id存儲在映射到索引的dict中。這不會增加運行時複雜性。

ld = [] 
encountered_id_index = {} 
for a, b, c, d, e in z: 
    if a in encountered_id_index: 
     index = encountered_id_index[a] 
     ld_dict = ld[index] 
     ld_dict['hashtags'].append({'platform': d, 'hashtag': e, 'tag_id': c}) 
    else: 
     ld.append({ 'id': a, 
        'name': b, 
        'hashtags': [{'platform': d, 'hashtag': e, 'tag_id': c}] 
     }) 
     index = len(ld) - 1 
     encountered_id_index[a] = index 

這是未經測試的,但我認爲應該完成工作。

不相關,但我建議將for循環中的變量名更改爲更有意義的內容。 「id」而不是「a」,「name」而不是「b」等。我向你保證,如果你現在學會正確地命名你的變量,你將會減少未來的麻煩。它極大地提高了您的代碼的可讀性。

+1

100%同意不適當地命名變量。會改變這一點。 – NullException

+1

對OP的快速評論擴展了Geoff關於變量命名的註釋:通過捕獲異常並打印類似於「a是{a}和b是{b}並且c是{c}」的格式進行故障排除的能力。 \ n id:{id} \ n name:{name} \ ntag_id:{tag_id} \ n platform:{platform} \ n標記名:{tagname}「.format(** locals())'。在將代碼發佈到生產環境之前,請確保失去對'locals'的任何引用 - 您實際上不應該依賴暴露整個命名空間來使代碼生效! –

+1

@Geoff - 接受(輕微編輯)你的答案是簡單,優雅,而不使用任何其他數據結構。儘管爲了學習,我也會嘗試其他答案。 tx – NullException

1
from collections import defaultdict, namedtuple 

HashTag = namedtuple('HashTag', ['tag_id', 'platform', 'tag_name']) 

class Entries: 
    def __init__(self): 
     self.entries = defaultdict(list) 

    def add_entry(self, id, name, tag_id, platform, tag_name): 
     key = (id, name) 
     value = HashTag(tag_id, platform, tag_name) 
     self.entries[key].append(value) 

z1 = Entries() 
for entry in z: 
    z1.add_entry(*entry) 

...我喜歡這個唯一的事情是,你需要知道這兩個ID 名稱查找條目。如果我認真地使用它,我會修改它以僅在id上索引條目,然後有第二個字典將name連接到id,然後實現__ getitem __,以便它可以對id或name進行查找。

+0

應該做'class Entries(object):'遵循新的類定義(允許像裝飾器之類的東西)。否則,我正在努力通過自己的一個極好的答案。 –

+0

@adsmith:對於Python 2.x,是的;在Python 3.x中不再需要 –