繁体   English   中英

不区分大小写的集合交集

[英]Case-insensitive set intersection

执行以下不区分大小写的交集的最佳方法是什么:

a1 = ['Disney', 'Fox']
a2 = ['paramount', 'fox']
a1.intersection(a2)
> ['fox']

通常我会做一个列表理解来将两者都转换为所有小写的:

>>> set([_.lower() for _ in a1]).intersection(set([_.lower() for _ in a2]))
set(['fox'])

但它有点难看。 有一个更好的方法吗?

使用set comprehension语法稍微不那么难看:

>>> {str.casefold(x) for x in a1} & {str.casefold(x) for x in a2}
{'fox'}

算法是相同的,并且没有更有效的方法可用,因为字符串的哈希值区分大小写。

使用str.casefold而不是str.lower将对国际数据更正确,并且自Python 3.3+起可用。

这里的定义存在一些问题,例如,字符串在具有两个不同情况的同一集合中出现两次,或者在两个不同的集合中出现(我们保留哪一个?)。

话虽这么说,如果你不关心,并且你想要多次执行这种交叉,你可以创建一个case不变的字符串对象:

class StrIgnoreCase:
  def __init__(self, val):
    self.val = val

  def __eq__(self, other):
    if not isinstance(other, StrIgnoreCase):
        return False

    return self.val.lower() == other.val.lower()

  def __hash__(self):
    return hash(self.val.lower())

然后我只维护两个集合,使它们包含这些对象而不是纯字符串。 每次创建新集和每个交集操作都需要较少的转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM