不区分大小写的集合交集

时间:2018-10-12 16:17:20

标签: python

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

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

通常我会进行列表理解,以将两者都转换为小写字母:

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

但是有点难看。有更好的方法吗?

2 个答案:

答案 0 :(得分:7)

使用set comprehension语法不太麻烦:

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

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

使用str.casefold代替str.lower可以更正确地处理国际数据,并且自Python 3.3+起可用。

答案 1 :(得分:1)

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

话虽如此,如果您不在乎,并且想要多次执行这种交集,则可以创建大小写不变的字符串对象:

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())

然后我将只维护这两个集合,以便它们包含这些对象而不是纯字符串。每次创建新集和进行每个相交操作时,所需的转换次数都会减少。