2

这可能是一个简单的问题,但我自己无法找到一个直接的答案。

给定两个列表,一个只有一个 id 列表,另一个包含所有数据,包括一些我们不关心的 id:
all_data = [['abc', 123], ['cde', 234], ['fgh', 345]]
ids = ['abc', 'fgh']

获得以下输出的最佳方法是什么,请注意它只保留那些具有相同 ID 的输出: new_data = [['abc', 123], ['fgh', 345]]

我当前的代码执行以下操作:

for x in all_data:
    for y in ids:
         if x[0] == y:
              new_data.append(x)

你会怎么做?是否有一个内置功能可以解决我在某处错过的问题?

(我说“类似”,因为它实际上是一个非常长的序列,涉及集合以及所有这一切,这就是为什么没有“pythonic”单线可以共享的原因。)

更新:你们很有趣。

要不我让它更难一点。如果我有一个字典 all_data_dict 而不是“all_data”,它有几个与“all_data”格式相同的列表条目怎么办?按照规则,我会确保接受原始问题的答案,但如果你们都想跟上乐趣,让我们看看我们得到了什么!

4

5 回答 5

7

使用列表推导,其中条件检查集合中的成员资格:

>>> all_data = [['abc', 123], ['cde', 234], ['fgh', 345]]
>>> ids = ['abc', 'fgh']
>>> id_set = set(ids)
>>> [s for s in all_data if s[0] in id_set]
[['abc', 123], ['fgh', 345]]
于 2012-08-09T21:40:14.660 回答
7

评论后编辑,我的意思是使用一套。正如雷蒙德在他的回答中建议的那样,使用带有一组 ID 的列表理解:)。

all_data = [['abc', 123], ['cde', 234], ['fgh', 345]]
ids = set(['abc', 'fgh'])
filtered_data = [x for x in all_data if x[0] in ids]
于 2012-08-09T21:40:41.510 回答
2

你应该all_data变成一本字典,因为你像一个字典一样使用它:

d = dict(all_data)
new_data = [(k, d[k]) for k in ids]

这将使用 给出的顺序ids,而不是 给出的顺序all_data

于 2012-08-09T21:40:57.833 回答
2

有很多人使用过 dicts 或 LC 我想我应该展示filter

>>> all_data = [['abc', 123], ['cde', 234], ['fgh', 345]]    
>>> ids = set(['abc', 'fgh'])
>>> values = filter(lambda value: value[0] in ids, all_data)
>>> values
[['abc', 123], ['fgh', 345]]
>>> 

至于第二部分。

>>> all_data_dict = {'abc':all_data, 'cde':all_data, 'fgh':all_data}
>>> ids = set(['abc', 'fgh'])
>>> dict(filter(lambda value: value[0] in ids, all_data_dict.items()))
{'abc': [['abc', 123], ['cde', 234], ['fgh', 345]], 'fgh': [['abc', 123], ['cde', 234], ['fgh', 345]]}
于 2012-08-09T21:45:34.643 回答
0

您的第二个问题并不难,只是从一开始就构建数据的正确方法:

>>> all_data = {'abc': 123, 'cde': 234,'fgh': 345}  # a dict
>>> ids = {'abc', 'fgh'}  # a set
>>> {k:v for k,v in all_data.viewitems() if k in ids}
{'abc': 123, 'fgh': 345}

顺便说一句,获取匹配键的一个很好的快速方法是:

>>> all_data.viewkeys() & ids 
set(['abc', 'fgh'])
于 2012-08-14T09:00:42.453 回答