代码之家  ›  专栏  ›  技术社区  ›  Technical Bard

在字符串列表中查找部分字符串-python

  •  0
  • Technical Bard  · 技术社区  · 16 年前

    我正在尝试检查用户是否是Active Directory组的成员,我有:

    ldap.set_option(ldap.OPT_REFERRALS, 0)
    try:
      con = ldap.initialize(LDAP_URL)
      con.simple_bind_s(userid+"@"+ad_settings.AD_DNS_NAME, password)
      ADUser = con.search_ext_s(ad_settings.AD_SEARCH_DN, ldap.SCOPE_SUBTREE, \  
               "sAMAccountName=%s" % userid, ad_settings.AD_SEARCH_FIELDS)[0][1]
    except ldap.LDAPError:
      return None
    

    ADUser 返回字符串列表:

    {'givenName': ['xxxxx'],
     'mail': ['xxxxx@example.com'],
     'memberOf': ['CN=group1,OU=Projects,OU=Office,OU=company,DC=domain,DC=com',
                  'CN=group2,OU=Projects,OU=Office,OU=company,DC=domain,DC=com',
                  'CN=group3,OU=Projects,OU=Office,OU=company,DC=domain,DC=com',
                  'CN=group4,OU=Projects,OU=Office,OU=company,DC=domain,DC=com'],
     'sAMAccountName': ['myloginid'],
     'sn': ['Xxxxxxxx']}
    

    当然,在现实世界中,组名是冗长的,并且结构多样,用户将属于数十或数百个组。

    如果我把组的列表作为 ADUser.get('memberOf')[0] ,检查主列表中是否存在单独列表的任何成员的最佳方法是什么?

    例如,检查列表将是 ['group2', 'group16'] 我想得到一个正确/错误的答案 任何 在主列表中存在较小的列表。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Alex Martelli    16 年前

    如果您给出的格式示例有些可靠,比如:

    import re
    grps = re.compile(r'CN=(\w+)').findall
    
    def anyof(short_group_list, adu):
      all_groups_of_user = set(g for gs in adu.get('memberOf',()) for g in grps(gs))
      return sorted(all_groups_of_user.intersection(short_group_list))
    

    在哪里传递列表,例如 ['group2', 'group16'] 作为第一个论点, ADUser dict作为第二个参数;这将返回按字母顺序排序的组列表(可能为空,表示“无”),其中包括 short_group_list ,用户所属的。

    仅仅是一个bool可能不会快得多,但是,如果您坚持,将函数的第二个语句更改为:

      return any(g for g in short_group_list if g in all_groups_of_user)
    

    可能在“真”的情况下节省一定的时间(因为 any 短路),尽管我怀疑不是在“错误”的情况下(必须遍历整个列表)。如果您关心性能问题,最好的方法是将这两种可能性都基准到对您的用例实际可行的数据上!

    如果性能还不够好(如您所说,bool yes/no就足够了),请尝试反转循环逻辑:

    def anyof_v2(short_group_list, adu):
      gset = set(short_group_list)
      return any(g for gs in adu.get('memberOf',()) for g in grps(gs) if g in gset)
    

    任何 在这里,短路能力可能更有用(至少在“真”的情况下,再次证明——因为,再次证明,没有办法在不检查所有可能性的情况下给出“假”结果!-)。

        2
  •  1
  •   ars    16 年前

    分析组列表后,可以使用集合交集(&operator)。例如:

    > memberOf = 'CN=group1,OU=Projects,OU=Office,OU=company,DC=domain,DC=com'
    
    > groups = [token.split('=')[1] for token in memberOf.split(',')]
    
    > groups
    ['group1', 'Projects', 'Office', 'company', 'domain', 'com']
    
    > checklist1 = ['group1', 'group16']
    
    > set(checklist1) & set(groups)
    set(['group1'])
    
    > checklist2 = ['group2', 'group16']
    
    > set(checklist2) & set(groups)
    set([])
    

    请注意,对集合进行条件计算的工作方式与对列表和元组的工作方式相同。如果集合中有任何元素,则为true,否则为false。所以, "if set(checklist2) & set(groups): ..." 不会执行,因为在上面的示例中,条件的计算结果为false(checklist1测试的结果为true)。

    还可以看到:

    http://docs.python.org/library/sets.html

    推荐文章