进行以下不区分大小写的交集的最佳方法是什么?
a1 = ['Disney', 'Fox']
a2 = ['paramount', 'fox']
a1.intersection(a2)
> ['fox']
通常我会进行列表理解,以将两者都转换为小写字母:
>>> set([_.lower() for _ in a1]).intersection(set([_.lower() for _ in a2]))
set(['fox'])
但是有点难看。有更好的方法吗?
答案 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())
然后我将只维护这两个集合,以便它们包含这些对象而不是纯字符串。每次创建新集和进行每个相交操作时,所需的转换次数都会减少。