这可能是一个简单的问题,但我无法自己找到一个直截了当的答案。
给出两个列表,一个只有一个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”我有一个字典all_data_dict,它有几个与“all_data”格式相同的列表条目怎么办?按照规则,我会确保接受原始问题的答案,但是如果你们都希望跟上这些乐趣,那么让我们看看我们得到了什么!
答案 0 :(得分: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]]
答案 1 :(得分:7)
在评论后编辑,我打算使用一套。 正如雷蒙德在他的回答中建议使用列表理解:)和一组ids。
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]
答案 2 :(得分:2)
您应该将all_data
变成字典,因为您可以像使用它一样:
d = dict(all_data)
new_data = [(k, d[k]) for k in ids]
这将使用ids
给出的顺序,而不是all_data
给出的顺序。
答案 3 :(得分: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]]}
答案 4 :(得分: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'])