2014-02-10 144 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中不再需要 –