0

我正在尝试学习 Python,虽然我设法偶然发现了当前问题的答案,但我想知道将来如何更好地找到答案。

我的目标是将字符串列表作为输入,并返回一个字符串,其字符是字符串中字符的并集,例如

unionStrings( ("ab", "bc"))

将返回“abc”。

我是这样实现的:

def unionStrings( strings ):
     # Input: A list of strings
     # Output: A string that is the (set) union of input strings
    all = set()
    for s in strings:
         all = all.union(set(s))

    return "".join(sorted(list(all)))

我觉得 for 循环是不必要的,并寻找更整洁、更 Pythonic(?) 的改进。

第一个问题:我偶然发现了使用类方法set.union(),而不是set1.union(set2). 我应该能够在标准 Python 文档中找到它吗?我没能在那里找到它。

所以我尝试像这样使用 set.union() :

>>> set.union( [set(x) for x in ("ab","bc")] )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'union' requires a 'set' object but received a 'list'

再一次,我跌跌撞撞,最后发现我应该这样称呼它:

>>> set.union( *[set(x) for x in ("ab","bc")] )
set(['a', 'c', 'b'])

第二个问题:我认为这意味着set.union(有效地)声明为

set.union( *sets)

并不是

set.union( setsList ) 

那是对的吗?(我还在学习如何使用 splat '*'。)

第三个问题:我在哪里可以找到关于签名的文件set.union()?我在 set/freezeset 文档中没有看到它,我无法让inspect模块给我任何东西。我什至不确定set是一个模块,它似乎是一个类型。它是在模块中定义的,还是什么?

感谢您阅读我的复杂问题。更多的是“我如何浏览 Python 文档?” 而不是“我如何在 Python 代码中做到这一点?”。


回应 jonrsharpe 的评论:

哦哦哦!我已经习惯了在 C++ 中定义单独的静态和实例方法。既然你解释了它,我真的可以看到发生了什么。

我唯一可能做的不同就是把它写成

t = set.union( *[set(x) for x strings] )
return "".join(sorted(t))

因为当它们在功能上没有扮演不同的角色时,将它们strings[0]与字符串区别对待让我感到困扰。strings[1:]如果我必须调用set()其中一个,我宁愿调用所有这些,因为union()无论如何都会这样做。但这只是风格,对吧?

4

1 回答 1

2

There are several questions here. Firstly, you should know that:

Class.method(instance, arg)

is equivalent to:

instance.method(arg)

for instance methods. You can call the method on the class and explicitly provide the instance, or just call it on the instance.

For historical reasons, many of the standard library and built-in types don't follow the UppercaseWords convention for class names, but they are classes. Therefore

set.union(aset, anotherset)

is the same as

aset.union(anotherset)

set methods specifically can be tricky, because of the way they're often used. set.method(arg1, arg2, ...) requires arg1 to already be a set, the instance for the method, but all the other arguments will be converted (from 2.6 on).

This isn't directly covered in the set docs, because it's true for everything; Python is pretty consistent.

In terms of needing to "splat", note that the docs say:

union(other, ...)

rather than

union(others)

i.e. each iterable is a separate argument, hence you need to unpack your list of iterables.


Your function could therefore be:

def union_strings(strings):
    if not strings:
        return ""
    return "".join(sorted(set(strings[0]).union(*strings[1:])))

or, avoiding the special-casing of strings[0]:

def union_strings(strings): 
    if not strings:
        return ""
    return "".join(sorted(set.union(*map(set, strings))))
于 2014-08-05T19:53:41.713 回答