【问题标题】:How to look for elements in a set that satisfy a certain condition on the element itself?如何在集合中查找满足元素本身特定条件的元素?
【发布时间】:2018-08-23 02:12:33
【问题描述】:

我有一个集合,其中每个元素都是 2 个元组的元组,每个元组自身包含 3 个元素/字段,例如,集合的一个元素看起来像:

(('q0','l0','s0'),('q1','l1','s1'))

我需要查找集合元素的特定字段。 我现在这样做的方式是:

            for set_element in my_set:
                s0 = set_element[0]
                s1 = set_element[1]

                if s0 == '('q0','l0','s0')':
                     "add this set_element to another set"

现在这行得通,但是对于集合中的大量元素,我觉得这不是很有效,因为每次我都必须遍历集合中的所有元素,而我无法利用集合的效率.

有没有更有效的方法呢?考虑到我可能还需要访问一个特定的字段,比如 'q0'

编辑: 我会做一个更详细的例子,假设我有这组元素:

 x= [(('q0','l0','s0'),('q1','l1','s1')),(('q0','l1','s0'), 
('q1','l2','s2')),(('q0','l0','s4'),('q1','l1','s1')), 
(('q2','l2','s2'),('q3','l3','s3')),(('q4','l4','s4'),('q5','l5','s5'))]

并且我想提取第一个元组具有 q0 作为元素的所有元素,所以在这种情况下,结果将是

(('q0','l0','s0'),('q1','l1','s1'))
(('q0','l1','s0'),('q1','l2','s2'))
(('q0','l0','s4'),('q1','l1','s1'))

【问题讨论】:

  • 您可以尝试使用集合推导来聚合所有必需的元素。然后用这个聚合集更新“另一个集”。
  • 你能给我一个简单的例子来说明你会怎么做吗?
  • 您能否提供一些数据(不必很大,只需多个元素)以便我们进行基准测试吗?信不信由你,创建测试数据是一种降低响应者兴趣的手动工作!
  • @jpp 是的,当然。我在问题中添加了它,以便更容易阅读

标签: python hash set


【解决方案1】:

我会使用字典而不是元组的元组,因为您只比较元组对中的第一项,我们可以将其用作键,并将元组中的第二个元素用作值。然后您可以简单地利用字典查找速度。

x = [(('q0','l0','s0'),('q1','l1','s1')),(('q2','l2','s2'),('q3','l3','s3')),(('q4','l4','s4'),('q5','l5','s5'))]

d = {a:b for a,b in x}

if ('q0','l0','s0') in d.keys():
    print(d[('q0','l0','s0')]) # or do something like adding it to another set

请注意,这仅适用于元组对的第一个元素是唯一的。如果不是,您必须稍微更改字典的创建方式,通过检查键是否存在,如果存在则创建一个值列表,但这是离题,只是推测细节。

如果您只需要搜索q0,您可以简单地遍历每个键,并检查q0 是否属于该键。除非您将元组展平并将值列表作为键,否则您将无法解决此问题:

for each in d.keys():
    if 'q0' in each:
        print(d[('q0','l0','s0')])

如果这不是您要查找的内容,那么字典可能不是您的解决方案。您也可以仅将密钥存储为 q0 以获取整个外部 for each in d.keys(),但这再次取决于您的要求,您说您需要能够搜索 ('q0','l0','s0') 和 q0。

【讨论】:

  • 这可能是一个选项,但假设我需要提取第一个字段等于'q0'的所有元素,无论 l 和 s 是什么,我将如何处理?
  • 我明白了,遍历字典的所有元素并检查条件正是我想要避免的,因为我有很多元素。你会用什么来代替字典?
  • 然后是某种数据库,可能是 pandas,也可能是 sql 数据库。但如果您想快速访问大型数据集,这就是数据库的用途。
【解决方案2】:

通过使用集合推导而不是显式循环,您可能会看到大约 30% 的速度提升:

x = [(('q0','l0','s0'),('q1','l1','s1')),
     (('q0','l1','s0'),('q1','l2','s2')),
     (('q0','l0','s4'),('q1','l1','s1')), 
     (('q2','l2','s2'),('q3','l3','s3')),
     (('q4','l4','s4'),('q5','l5','s5'))]

x = x*100000

def original(x):
    res = set()
    for set_element in x:
        s0 = set_element[0]
        if s0[0] == 'q0':
            res.add(set_element)
    return res

def jp(x):
    return {k for k in x if k[0][0] == 'q0'}

%timeit original(x)  # 110ms
%timeit jp(x)        # 77ms

【讨论】:

    【解决方案3】:

    如果你愿意,你可以试试这些方法:

    x= [(('q0','l0','s0'),('q1','l1','s1')),(('q0','l1','s0'),
    ('q1','l2','s2')),(('q0','l0','s4'),('q1','l1','s1')),
    (('q2','l2','s2'),('q3','l3','s3')),(('q4','l4','s4'),('q5','l5','s5'))]
    
    print(list(filter(lambda x:x[0][0]=='q0',x)))
    

    秒

    def recursive(data):
    
        data1 = data[0]
        if data1[0][0] == 'q0':
            print(data1)
            return recursive(data[1:])
    
    
    print(recursive(x))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-14
      相关资源
      最近更新 更多