在Python中声明未知类型变量?

3 投票
11 回答
27511 浏览
提问于 2025-04-15 14:47

我在Python中遇到了一个情况(咳咳,作业),需要把给定列表中的每个元素乘以一个指定的次数,然后返回这些元素的结果。问题是,给出的示例输入类型各不相同。比如,有的输入是字符串列表,我需要对这些字符串进行乘法操作,而其他的可能是整数。所以我的返回类型需要根据输入的类型变化。我希望能做到这一点,而不需要去检查每个对象的类型。请问有没有办法做到这一点?我知道在C#中可以用“var”,但我不确定Python中是否有类似的东西。

我明白变量不需要声明,但在这种情况下,我找不到其他解决办法。以下是我写的函数:

def multiplyItemsByFour(argsList):

output = ????

for arg in argsList:
        output += arg * 4

return output

你看我需要在输出变量中添加内容。如果我试着去掉第一行的输出赋值,就会出现变量未定义的错误。但是如果我给它赋值为0或者""(空字符串),就可能会抛出异常,因为你不能把3加到字符串上,或者把"a"加到整数上,等等……

这里有一些示例输入和输出:

Input:  ('a','b')  Output:  'aaaabbbb'
Input:  (2,3,4)    Output:  36

谢谢!

11 个回答

2

你确定这适合Python初学者吗?在我看来,最简单的做法是用reduce()和lambda这两个工具,但这两个工具对初学者来说并不常见,有时候甚至连经验丰富的Python程序员也不太推荐使用:

def multiplyItemsByFour(argsList):
    if not argsList:
        return None
    newItems = [item * 4 for item in argsList]
    return reduce(lambda x, y: x + y, newItems)

就像Alex Martelli一样,我在开头加了一个快速测试,用来处理空列表,这样会返回None。需要注意的是,如果你使用的是Python 3,你必须导入functools才能使用reduce()。

其实,reduce(lambda...)的解决方案和其他建议很相似,都是用第一个输入项来设置一个累加器,然后处理其余的输入项;不过这种写法更简洁。

7
def fivetimes(anylist):
  return anylist * 5

如你所见,如果你有一个列表作为参数,就不需要任何赋值操作来“将其乘以给定的次数并返回结果”。你提到一个给定的列表;如果不是作为你函数的参数,那它是怎么给定给你的呢?当然,这并不太重要——即使它是一个全局变量,或者是你参数对象的一个属性,这也不需要任何赋值。

如果你被“作业”禁止使用列表的*操作符,而只要求你自己实现,这就需要赋值,但不需要声明:

def multiply_the_hard_way(inputlist, multiplier):
    outputlist = []
    for i in range(multiplier):
        outputlist.extend(inputlist)
    return outputlist

你可以简单地让空列表“神奇地出现”:不需要“声明”它是什么,它就是一个空列表,Python编译器和你一样都知道这一点。将它绑定到名字outputlist上也不需要你做任何特别的仪式,只需要绑定(也就是赋值)本身:名字没有类型,只有对象有类型……这就是Python!-)

编辑:原作者现在说输出不能是列表,而应该是整数、浮点数或字符串,并且没有给出具体指示。我已经请求澄清——乘以一个列表总是返回一个列表,所以显然他必须是指与他最初所说的不同的东西,即他必须乘以一个列表。与此同时,这里有另一个猜测。也许他必须返回一个列表,其中输入列表的每个项目都乘以相同的因子(无论该项目是整数、浮点数、字符串、列表……)。那么:

define multiply_each_item(somelist, multiplier):
  return [item * multiplier for item in somelist]

看,妈,没有手^H^H^H^H^H赋值。(顺便说一下,这被称为“列表推导”)。

或者也许(不太可能,但我猜测的帽子可能受到铝箔帽的干扰,需要去疯帽子的商店调试一下)他需要(比如说)将每个列表项当作与第一个项相同的类型来乘,但返回它们的原始类型,比如说:

>>> mystic(['zap', 1, 23, 'goo'], 2)
['zapzap', 11, 2323, 'googoo']
>>> mystic([23, '12', 15, 2.5], 2)
[46, '24', 30, 4.0]

即使这个高度神秘的规范也可以适应……:

>>> def mystic(alist, mul):
...   multyp = type(alist[0])
...   return [type(x)(mul*multyp(x)) for x in alist]
... 

……尽管我非常怀疑这就是作业中神秘符文实际编码的规范。几乎任何精确的规范都可以被实现,或者被证明在陈述的情况下可能是不可能的(比如要求你解决停机问题或要求P==NP;-)。这可能需要一些工作(例如“证明四色定理”;-)……但仍然比从一堆相互矛盾的观察、没有例子的情况下神奇地推测出实际规范要少得多。尽管在我们作为软件开发者的日常工作中(啊,真希望过去的日子里我们只需面对作业!-)我们当然会遇到很多这样的情况(并且必须解决它们以谋生;-)。

编辑编辑:终于看到一个精确的规范,我指出我已经实现了那个,反正,这里再来一次:

def multiplyItemsByFour(argsList):
  return [item * 4 for item in argsList]

编辑编辑编辑:终于/终于看到一个更精确的规范,带有(奢侈!-)示例

Input: ('a','b') Output: 'aaaabbbb' Input: (2,3,4) Output: 36

所以想要的是输入列表中每个项目乘以四的求和(而且你不能使用sum,因为它对字符串无效)。我喜欢的解决方案:

def theFinalAndTrulyRealProblemAsPosed(argsList):
  items = iter(argsList)
  output = next(items, []) * 4
  for item in items:
    output += item * 4
  return output

如果你被禁止使用某些构造,比如内置的itemsiter,还有很多其他可能性(稍微差一些的)比如:

def theFinalAndTrulyRealProblemAsPosed(argsList):
  if not argsList: return None
  output = argsList[0] * 4
  for item in argsList[1:]:
    output += item * 4
  return output

对于一个空的argsList,第一个版本返回[],第二个版本返回None——我不确定在这种边缘情况下你应该怎么做。

2

在Python中,这个过程非常简单。你需要先确定你列表中数据的类型——可以对第一个元素使用type()函数,也就是type(argsList[0])。接下来,为了初始化输出(现在你可能有一个????),你需要这个类型的“零”值或空值。就像int()、float()或str()函数会返回它们各自类型的零值一样,type(argsList[0])()也会返回你列表中数据类型的零值或空值。

所以,这里是你的函数,做了一个小小的修改:

def multiplyItemsByFour(argsList):
    output = type(argsList[0])()
    for arg in argsList:
        output += arg * 4
    return output

适用于:
argsList = [1, 2, 3, 4][1.0, 2.0, 3.0, 4.0]"abcdef" ...等等。

撰写回答