将dict与相同的键组合成一个带有列表的dict

时间:2014-06-30 18:10:16

标签: python dictionary

我有一个dicts元组,我从mysql服务器收到答案。

({
    'firstname': 'Alexandro',
    'Title': 'My life',
    'lastname': 'Riviera',
    'articles.id': 6L,
    'authorId': 1L,
    'id': 1L
}, {
    'firstname': 'Alexandro',
    'Title': 'My life 2',
    'lastname': 'Riviera',
    'articles.id': 7L,
    'authorId': 1L,
    'id': 1L
}, {
    'firstname': 'Helen',
    'Title': 'Learn SQL',
    'lastname': 'Oldgarno',
    'articles.id': 8L,
    'authorId': 2L,
    'id': 2L
}, {
    'firstname': 'Helen',
    'Title': 'SQL for you',
    'lastname': 'Oldgarno',
    'articles.id': 9L,
    'authorId': 2L,
    'id': 2L
})

我想用相同的键“authorId”转换成:

({
    'firstname': 'Alexandro',
    'lastname': 'Riviera',
    'id': 1L,
    'articles': [{
        'articles.id': 6L,
        'authorId': 1L,
        'Title': 'My life'
    }, {
        'articles.id': 7L,
        'authorId': 1L,
        'Title': 'My life 2'
    }]
}, {
    'firstname': 'Helen',
    'lastname': 'Oldgarno',
    'id': 2L,
    'articles': [{
        'articles.id': 8L,
        'authorId': 2L,
        'Title': 'Learn SQL'
    }, {
        'articles.id': 9L,
        'authorId': 2L,
        'Title': 'SQL for you'
    }]
})

我不知道如何以非常丑陋的方式完成这项任务。任何建议都会有所帮助!

2 个答案:

答案 0 :(得分:0)

您可以将其转换为列表并按authorID排序。一旦您能够根据authorID分离它们,您肯定可以折叠作者信息字段并将文章信息放入列表中。

答案 1 :(得分:0)

你可以编写这样的合并函数,但你真的应该考虑重写你的SQL查询。这是一个简单的解决方案:

def merge_books(books):
    merged = {}

    for book in books:
        authorId = book['authorId']

        # Create article attribute
        book['articles'] = [{
            'articles.id': book['articles.id'],
            'authorId':    book['authorId'],
            'Title':       book['Title'],
        }]

        # Remove redundant information
        del book['articles.id']
        del book['authorId']
        del book['Title']

        if authorId in merged:
            merged[authorId]['articles'].append(book['articles'][0])
        else:
            merged[authorId] = book

    # Convert dict into a tuple, but why not a list?
    return tuple(merged.values())

更好的方法是使用两个select语句并将它们的结果合并在一起:

import MySQLdb

def get_authors_with_articles(connection):
    cursor = connection.cursor()

    authors = {}
    for author in cursor.execute('SELECT * FROM Authors'):
        # Initialize empty article list that will be popluated with the next select
        author['articles'] = []
        authors[author['id']] = author

    for article in cursor.execute('SELECT * FROM Articles').fetchall():
        # Fetch and delete redundant information
        author_id = article['authorId']
        del article['authorId']

        authors[author_id]['articles'].append(article)

    return list(authors.values())


if __name__ == '__main__':
    connection = MySQLdb.connect(
        mysql_host,
        mysql_user,
        mysql_pass,
        mysql_base,
        cursorclass=MySQLdb.cursors.DictCursor
    )
    print(get_authors_with_articles(connection))