高效地查找python关联列表中的元素

2024-10-01 02:37:41 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组清单如下:

conditions = [
["condition1", ["sample1", "sample2", "sample3"]],
["condition2", ["sample4", "sample5", "sample6"],
...]

如何在Python中高效优雅地完成以下任务?在

  1. 找到某个条件下的所有元素?在

    把条件2中所有的样品都拿出来。现在我可以:

    ^{pr2}$

    但那太笨重了。

  2. 找到条件列表的有序联合?E、 g.ordered_union(["condition1", "condition2"], conditions)应返回:

    ["sample1", "sample2", "sample3", "sample4", "sample5", "sample6"]
    

如何在Python中有效地实现这一点?可能有聪明的一句话?在


Tags: 元素列表样品条件conditions有序sample2sample1
3条回答

您需要使用dict(字典),而不是list。另外,如果您想要高效的基于集合的操作,可以将样本保存在set中。在

conditions = { "condition1" : set(["sample1", "sample2", "sample3"]),
               "condition2" : set(["sample4", "sample5", "sample6"]) }

print conditions["condition2"]
# set(['sample5', 'sample4', 'sample6'])
union = conditions["condition1"].union(conditions["condition2"])
print sorted(union)
# ['sample1', 'sample2', 'sample3', 'sample4', 'sample5', 'sample6']

这看起来更像是dict的工作:

conditions = {
"condition1": ["sample1", "sample2", "sample3"],
"condition2": ["sample4", "sample5", "sample6"],
...}

然后可以使用

^{pr2}$

在Python3.1或2.7中,可以使用OrderedDict来保留顺序:

from collections import OrderedDict
conditions = OrderedDict([
["condition1", ["sample1", "sample2", "sample3"]],
["condition2", ["sample4", "sample5", "sample6"]]
])

然后,您可以得到“有序联合”,同样适用于任意大小的OrderedDicts

>>> import itertools
>>> [item for item in itertools.chain(*conditions.values())]
['sample1', 'sample2', 'sample3', 'sample4', 'sample5', 'sample6']

好吧,如果你被迫保留那些笨重的数据结构,你就不能期望太多。第一个解决方案的一行代码相当于:

def samplesof(requested_cond, conditions):
    return next(s for c, s in conditions if c==requested_cond)

对于第二个问题,如果你坚持一句话,它会是这样的:

^{pr2}$

有更快的方法来解决第二个问题,但都是多行的,例如:

aux_set = set(the_conds)
samples_by_cond = dict((c, s) for c, s in conditions if c in aux_set)
return [s for c in the_conds for s in samples_by_cond[c]]

请注意,后一种方法之所以更快,关键在于它使用了正确的数据结构(set和dict)——不幸的是,它必须自己构建它们,因为传入的{}嵌套列表实际上是错误的数据结构。在

您不能将conditions封装为一个类的成员变量,该类只构建一次关键的(正确的,快速的)辅助数据结构?E、 g.:

class Sensible(object):
  def __init__(self, conditions):
    self.seq = []
    self.dic = {}
    for c, s in conditions:
      self.seq.append(c)
      self.dic[c] = s
  def samplesof(self, requested_condition):
    return self.dic[requested_condition]
  def ordered_union(self, the_conds):
    return [s for c in the_conds for s in self.dic[c]]

现在又快又优雅!在

我假设您需要self.seq(条件序列)来执行其他操作(对于您提到的两个操作,它肯定不需要!),并且在这个序列和样本中没有重复(无论你的实际规格是什么,它们都不会很难接受,但是当你没有提到它们的时候,盲目地去猜测它们是非常困难和毫无意义的;-)。在

相关问题 更多 >