[英]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.