在Python中处理单值元组的最佳实践是什么?

18 投票
9 回答
21884 浏览
提问于 2025-04-15 18:19

我在使用一个第三方库的函数,这个函数会从一个文件中读取一组关键词,并应该返回一个值的元组。只要关键词有两个或更多,它的工作是正常的。但是,如果只有一个关键词,它返回的却是一个普通字符串,而不是一个包含一个元素的元组。这就很麻烦,因为当我尝试像这样做的时候

for keyword in library.get_keywords():
    # Do something with keyword

在只有一个关键词的情况下,for循环会逐个字符地遍历这个字符串,这样不会抛出任何异常,无论是在运行时还是其他情况下,但对我来说完全没有用。

我有两个问题:

首先,这显然是库中的一个bug,我无法控制。那我该如何最好地解决这个问题呢?

其次,通常来说,如果我写一个返回元组的函数,确保返回的元组包含一个元素的最佳做法是什么?比如说,如果我有

def tuple_maker(values):
    my_tuple = (values)
    return my_tuple

for val in tuple_maker("a string"):
    print "Value was", val

for val in tuple_maker(["str1", "str2", "str3"]):
    print "Value was", val

我得到的是

Value was a
Value was  
Value was s
Value was t
Value was r
Value was i
Value was n
Value was g
Value was str1
Value was str2
Value was str3

那么,如何修改函数my_tuple,以便在只有一个元素时也能返回一个元组?我是否需要明确检查一下大小是否为1,然后使用(value,)的语法单独创建元组?这就意味着任何可能返回单值元组的函数都必须这样做,这看起来有点繁琐和重复。

有没有什么优雅的通用解决方案来处理这个问题呢?

9 个回答

3

你的 tuple_maker 函数并没有像你想的那样工作。和你定义的 tuple maker 相同的定义是:

def tuple_maker(input):
    return input

你看到的情况是,调用 tuple_maker("a string") 会返回一个字符串,而调用 tuple_maker(["str1","str2","str3"]) 会返回一个字符串列表;这两者都不是元组!

在 Python 中,元组是通过逗号来定义的,而不是用括号。因此 (1,2) 是一个包含值 12 的元组,而 (1,) 是一个只包含单个值 1 的元组。

要把一个值转换成元组,正如其他人所提到的,可以使用 tuple

>>> tuple([1])
(1,)
>>> tuple([1,2])
(1,2)
8

对于你的第一个问题,我不太确定这是否是最好的答案,但我觉得你需要自己检查一下返回的值是字符串还是元组,然后根据情况采取相应的措施。

至于你的第二个问题,任何变量都可以通过在它旁边加一个,来变成一个只有一个值的元组:

>>> x='abc'
>>> x
'abc'
>>> tpl=x,
>>> tpl
('abc',)

把这两个想法结合起来:

>>> def make_tuple(k):
...     if isinstance(k,tuple):
...             return k
...     else:
...             return k,
... 
>>> make_tuple('xyz')
('xyz',)
>>> make_tuple(('abc','xyz'))
('abc', 'xyz')

注意:在我看来,通常使用isinstance或者其他需要在运行时检查对象类型的逻辑并不是个好主意。不过对于这个问题,我觉得没有其他更好的办法。

22

你需要以某种方式检查一下这个东西是什么类型,是字符串还是元组。我会这样做:

keywords = library.get_keywords()
if not isinstance(keywords, tuple):
    keywords = (keywords,) # Note the comma
for keyword in keywords:
    do_your_thang(keyword)

撰写回答