2011-11-01 54 views
0

我正在使用Python 2.6,并且我有两个数据集,每个数据集都是一个字典列表。这两个数据集是这样的:根据匹配的字典键创建(k,v1,...,vn)元组

[{'foo': 3}, {'bar': 4}] 
[{'bar': 1}, {'foo': 8}] 

从这两个数据集,我想创建元组是这样的输入数据的一个列表:

[('foo', 3, 8), ('bar', 4, 1)] 

这是非常重要的第一个数据集中的数字首先出现在结果元组中,顺便说一句。

我已经通过各种方法(包括嵌套列表理解)实际完成了这一点,但它似乎应该更简单/更清晰。我很惊讶itertools中没有任何东西跳出来(尽管我确实做了一个带链的实现,导致了一个2元组,其中的整数在列表中)。任何人都可以提供一个干净的解决方案,还是没有一个?

回答

3

您可以使用defaultdict

from collections import defaultdict 

datasets = [{'foo': 3}, {'bar': 4}], [{'bar': 1}, {'foo': 8}]  

result = defaultdict(list) 

for dataset in datasets: 
    for eachdict in dataset: 
     for key, value in eachdict.iteritems(): 
      result[key].append(value) 

# the nested loops as a one-liner (utterly unnecessary): 
# any(result[key].append(value) for dataset in datasets 
#        for eachdict in dataset 
#        for key, value in eachdict.iteritems()) 


# if you really need your output in exactly that format: 
# result = [(key,) + tuple(values) for key, values in result.iteritems()] 
print result 

这似乎是最干净的方式给我。

+0

这几乎就是我已经做好的准备,但是我认为我会为其他输入提供帮助。感谢您验证我的想法:) – jonesy

2

这是一个inner join operation,我们有一个工具,做的是:

>>> ds1 = [{'foo': 3}, {'bar': 4}] 
>>> ds2 = [{'bar': 1}, {'foo': 8}] 

>>> import sqlite3 
>>> c = sqlite3.connect(':memory:') 
>>> c.execute('CREATE TABLE ds1 (key text PRIMARY KEY, value text)') 
>>> c.execute('CREATE TABLE ds2 (key text PRIMARY KEY, value text)') 
>>> c.executemany('INSERT INTO ds1 VALUES (?, ?)', [d.items()[0] for d in ds1]) 
>>> c.executemany('INSERT INTO ds2 VALUES (?, ?)', [d.items()[0] for d in ds2]) 
>>> c.commit() 
>>> r = c.execute('SELECT ds1.key, ds1.value, ds2.value FROM ds1 INNER JOIN ds2 ON ds1.key=ds2.key') 
>>> list(r) 
[(u'foo', u'3', u'8'), (u'bar', u'4', u'1')] 

sqlite3 module Python自带的,不需要你为了执行SQL查询来创建和维护一个实际的数据库您数据集。因此,如果您没有从数据库获取数据,也无法更改查询以将其恢复为最适合您的应用程序的表单,则仍然可以使用SQL处理数据,这非常方便。

使用SQL方法有几个优点1)代码清楚地表达了它的意图(我将两个数据集加入到一个公共密钥中),2)它更容易考虑正确性问题(例如一个数据集中存在的密钥但而不是其他,3)很容易扩展到多个字段或切换到多字段键,4)可以指定排序。

+0

原始问题与一般的sqlite或数据库无关。 – jonesy

+0

@jonesy所以?这并不意味着你不能使用数据库来解决它。输出仍然是你想要的数据。无可否认,除非有明显的性能优势,否则我更喜欢用Python做它。 – agf

+0

原始问题也与defaultdicts没有任何关系。事实上,你正在做的是内部连接操作。尽管如此,你用它来解决这个问题。这篇文章的要点是人们经常使用字典来重新创建通用数据库操作,因为他们可能正在使用已经为其优化的工具。 –