簡體   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