如何验证传递给函数的嵌套元组的长度?

时间:2018-01-08 19:12:54

标签: python list tuples args

我正在构建一个接受元组列表的函数。例如:

my_list = [
     ("str1", 1, 11),
     ("str2", 2, 22), 
     ("str3", 3, 33),
     ("str4", 4, 44)
] 

我想创建一个定义的函数,它只接受每个嵌套元素大小的参数为" 3"。如何定义我的函数以仅接受我所需嵌套长度的列表?

以下是我想要实现的示例代码片段(我知道它在语法上是不正确的)

def newattr_ratio(data, *(name,idx,idy)):

    for name,idx,idy in *(name,idx,idy):
        data[name]= data[data.columns[idx]]/data[data[columns[idy]]]

如何创建具有此类参数定义的函数?

3 个答案:

答案 0 :(得分:1)

在声明功能参数期间,您不能限制它。但是,您可以创建自定义装饰器以检查嵌套元组的长度

from functools import wraps

def check_params(nestedsize=None):
    def _check_params(func):
        def _decorator(data, *args ):
            if nestedsize and all(len(arg)==nestedsize for arg in args):
                return func(data, *args)
            else:
                raise Exception("Invalid args passed with the function call")
        return wraps(func)(_decorator)
    return _check_params

上面的装饰器使用可选参数nestedsize来检查嵌套元组的大小。

现在,用于将解压缩版本的列表传递给您的函数,您的函数定义应为:

@check_params(nestedsize=3)    # <-- added decorator here, with nested size as "3"
def newattr_ratio(data, *args):  # <-- note the asterisk sign here
    for name, idx, idy in args:
        print("{} - {} - {}".format(name, idx, idy))

示例运行:

# Correct input
>>> my_list = [("a", 1, 11), ("b", 2, 22), ("c", 3, 33)]

#                     v asterisk again to unpack the list
>>> newattr_ratio([], *my_list)
a - 1 - 11
b - 2 - 22
c - 3 - 33

# Incorrect input, raising custom exception
>>> my_list = [("a", 1, 11, "wrong_data"), ("b", 2, 22), ("c", 3, 33)]

>>> newattr_ratio([], *my_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in _decorator
Exception: Invalid args passed with the function call

如果您不想解压缩列表并按原样传递,那么您的功能应该是:

@check_params(nestedsize=3) 
def newattr_ratio(data, args):  # <-- No asterisk here
    for name, idx, idy in args:
        print("{} - {} - {}".format(name, idx, idy))
        # ... whatever your logic is

示例运行(与上面相同的结果,唯一的区别在于函数调用)

# correct input
>>> my_list = [("a", 1, 11), ("b", 2, 22), ("c", 3, 33)]
>>> newattr_ratio([], my_list)   # <-- No asterisk here
a - 1 - 11
b - 2 - 22
c - 3 - 33

# Incorrect input, raising custom exception
>>> my_list = [("a", 1, 11, "wrong_data"), ("b", 2, 22), ("c", 3, 33)]

>>> newattr_ratio([], my_list)   # <-- No asterisk here
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in _decorator
Exception: Invalid args passed with the function call

但是如果你不能使用装饰器,那么你的for循环会将异常提升为ValueError: too many values to unpack。因此,如果你没有自定义异常

,你可以跳过装饰器

例如:

#                               v extra value here
>>> my_list = [("a", 1, 11, "wrong_data"), ("b", 2, 22), ("c", 3, 33)]

>>> newattr_ratio([], my_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in newattr_ratio
ValueError: too many values to unpack

答案 1 :(得分:0)

你有点不对劲。处理可变数量参数的格式是&#34; def newattr_ratio(data,* t_uple)&#34;。 &#34; * t_uple&#34;表示它将是可变数量的参数。一个例子如下:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script  src="https://use.fontawesome.com/911574fea4.js"></script>
<div class="v-container">
  <div class="v-content text-center">
    <div class="input">
      <input type="text" id="search" placeholder="Search...">
      <button class="icon"><i class="fa fa-search"></i></button>

      <table>
        <tr>
          <td class="fa fa-search">
            <td id="instant-search"></td>
        </tr>
      </table>
    </div>
  </div>
</div>

答案 2 :(得分:-1)

让函数接受元组列表作为参数

def newattr_ratio(data, myListOfTuples):
    for myTuple in myListOfTuples:
        data[myTuple[0]]= data[data.columns[myTuple[1]]/data[data[columns[myTuple[2]]]