【问题标题】:Python: Automatically change string to set in .intersection() method of Set?Python:在 Set 的 .intersection() 方法中自动更改要设置的字符串?
【发布时间】:2021-12-30 11:36:43
【问题描述】:

我是 Python 新手(并且具备 Java 的基本知识),目前通过使用 Head First Python, 2nd Edition 书自学它。

在书中的一个例子中,它展示了如何使用 Sets 的 .intersection() 方法。它通过以下方式这样做:

if __name__ == '__main__':
    def search_for_vowels(word: str) -> set:
        """Return any vowels found in supplied word."""
        vowels = set('aeiou')
        return vowels.intersection(set(word))

    print(search_for_vowels('hitch-hiker'))
    print(search_for_vowels('sky'))

但是,当我自己尝试时,我不小心忘记了上面代码中的“set”部分(在打印语句上方),因此它变成了:

if __name__ == '__main__':
    def search_for_vowels(word: str) -> set:
        """Return any vowels found in supplied word."""
        vowels = set('aeiou')
        return vowels.intersection(word)

    print(search_for_vowels('hitch-hiker'))
    print(search_for_vowels('sky'))

但是,代码运行时没有任何问题,并返回了正确的输出。这对我来说似乎有点奇怪,因为我会将集合与字符串进行比较,而不是将集合与集合进行比较。因此我的问题是:在执行 Set 的 intersection() 方法时,Python 是否会自动将字符串转换为集合?

提前致谢, 大卫

【问题讨论】:

    标签: python set intersection


    【解决方案1】:

    official docs, some set methods,包括intersection(),接受other的可迭代:

    注意,union()intersection()difference()symmetric_difference()issubset()issuperset() 方法的非运算符版本将接受任何可迭代作为参数 .相反,它们基于运算符的对应物要求它们的参数是集合。这排除了像 set('abc') & 'cbs' 这样容易出错的构造,而支持更易读的 set('abc').intersection('cbs')

    请注意,update()intersection_update()difference_update()symmetric_difference_update() 方法的非运算符版本将接受任何可迭代作为参数

    强调我的。可能没有发生转换(我没有检查源代码)。

    操作员 vs 非操作员

    来自文档:

    union(*其他
    set | other | ...
    返回一个包含集合中元素和所有其他元素的新集合。

    intersection(*其他
    set & other & ...
    返回一个新集合,其中包含集合和所有其他元素共有的元素。

    所以|union() 的运算符,&intersection() 的运算符。

    例子:

    >>> # using the & operator, with a set
    >>> set('abc') & set('cbs')
    {'c', 'b'}
    >>>
    >>> # using the intersection method, with a set
    >>> set('abc').intersection(set('cbs'))
    {'c', 'b'}
    >>>
    >>> # using the & operator, with non-set (error)
    >>> set('abc') & 'cbs'
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported operand type(s) for &: 'set' and 'str'
    >>>
    >>> # using the intersection method, with non-set (okay)
    >>> set('abc').intersection('cbs')
    {'c', 'b'}
    >>>
    >>> # also applies to general operations, see link below
    >>> # using the + operator with two integers
    >>> 4 + 5
    9
    >>> # using the __add__ method
    >>> (4).__add__(5)
    9
    

    看到这个list of operators and their methods/functions。一些内置类型,如集合和字典,也都有自己的运算符映射。并且使用__dunder__(双下划线x2)魔术方法,这些也可以为用户定义的对象实现。

    【讨论】:

    • 您好 Aneroid,感谢您的回复和官方文档。我想知道您是否能够解释非运营商版本和运营商版本之间的区别,因为我以前没有听说过这些术语。最诚挚的问候,大卫
    • @David 我添加了一些示例,对应于文档。欢迎来到 StackOverflow!如果有帮助,请阅读:What should I do when someone answers my question?,以及关于 acceptingvoting
    【解决方案2】:

    非运算符版本接受任何可迭代作为参数。我所说的非操作员是指这些操作的功能实现,例如.intersection().union() 等。

    如果要使用此操作的算子版本,则应设置所有变量。

    例如 -> set1 &amp; set2 需要两个 set 类型的操作数。

    【讨论】:

    • 嗨 Monark,感谢您的回答。这是我第一次听说 .intersection() 等的(非)运算符版本。您能解释一下两者之间的区别吗?最诚挚的问候,大卫
    • 区别可能在于.intersection() 的非运营商版本是&amp;,或者或多或少只是符号的区别? .intersection()的实际操作员版本是什么?
    • @David 是的,没错。有关示例,请参见我上面的 edited answer
    【解决方案3】:

    intersection 方法需要 iterable 作为参数。

    您正在传递一个可迭代的 string(word),因此它可以成功运行。

    【讨论】:

    • 嘿赛义德,非常感谢您的回复和帮助!
    • 当官方文档可以正常使用时,请不要链接到非官方和未经验证的来源。
    • @aneroid 感谢指出,更新了链接。
    猜你喜欢
    • 2013-11-04
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-29
    • 2020-10-06
    相关资源
    最近更新 更多