我正在尝试学习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循环是不必要的,并寻找更整洁,更python(?)的改进。
第一个问题:我无意中使用了类方法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()
无论如何都会这样做。但这只是一种风格,对吧?
这里有几个问题。首先,你应该知道:
Class.method(instance, arg)
等价于:
instance.method(arg)
实例方法。您可以在类上调用方法并显式地提供实例,或者仅在实例上调用它。
由于历史原因,许多标准库和内置类型没有遵循UppercaseWords
约定的类名,但是它们是类。因此
set.union(aset, anotherset)
与
相同aset.union(anotherset)
set
方法可能特别棘手,因为它们经常被使用。set.method(arg1, arg2, ...)
要求arg1
已经是set
,方法的实例,但所有其他参数将被转换(从2.6开始)。
这在set
文档中没有直接涉及,因为它对所有内容都是正确的;Python是相当一致的。
关于需要"splat",请注意文档中说:
union(other, ...)
而不是
union(others)
。每个可迭代对象都是一个单独的参数,因此您需要解包可迭代对象列表。
你的函数可以是:
def union_strings(strings):
if not strings:
return ""
return "".join(sorted(set(strings[0]).union(*strings[1:])))
或,避免strings[0]
的特殊大小写:
def union_strings(strings):
if not strings:
return ""
return "".join(sorted(set.union(*map(set, strings))))