【问题标题】:Handle either a list or single integer as an argument将列表或单个整数作为参数处理
【发布时间】:2010-11-03 04:36:32
【问题描述】:

函数应根据行名(在本例中为第 2 列)选择表中的行。它应该能够将单个名称或名称列表作为参数并正确处理它们。

这就是我现在所拥有的,但理想情况下不会出现这种重复的代码,并且会智能地使用异常之类的东西来选择正确的方式来处理输入参数:

def select_rows(to_select):
    # For a list
    for row in range(0, table.numRows()):
        if _table.item(row, 1).text() in to_select:
            table.selectRow(row)
    # For a single integer
    for row in range(0, table.numRows()):
        if _table.item(row, 1).text() == to_select:
            table.selectRow(row)

【问题讨论】:

    标签: python list function integer


    【解决方案1】:

    其实我同意Andrew Hare's answer,只需传递一个包含单个元素的列表。

    但如果你真的必须接受一个非列表,那么在这种情况下将它变成一个列表怎么样?

    def select_rows(to_select):
        if type(to_select) is not list: to_select = [ to_select ]
    
        for row in range(0, table.numRows()):
            if _table.item(row, 1).text() in to_select:
                table.selectRow(row)
    

    在单个项目列表上执行“in”的性能损失不太可能很高 :-) 但这确实指出了如果您的“to_select”列表可能很长,您可能需要考虑做的另一件事:考虑将其转换为一个集合,以便查找更有效。

    def select_rows(to_select):
        if type(to_select) is list: to_select = set( to_select )
        elif type(to_select) is not set: to_select = set( [to_select] )
    
        for row in range(0, table.numRows()):
            if _table.item(row, 1).text() in to_select:
                table.selectRow(row)
    

    【讨论】:

    • 目前认为使用isinstance而不是type更好,见stackoverflow.com/questions/1549801/…
    • 如果使用 isinstance,某些类型存在 2/3 兼容性问题。例如,字符串类型是 str(在 3 中)或 basestring(在 2.7 中)。您可以为此使用six.string_typessix.integer_types。不幸的是,没有six.float_types,所以如果你需要来自 Python 2.7 的long,你必须手动编写代码。
    【解决方案2】:

    你可以重新定义你的函数来接受任意数量的参数,像这样:

    def select_rows(*arguments):
        for row in range(0, table.numRows()):
            if _table.item(row, 1).text() in arguments:
                table.selectRow(row)
    

    然后你可以像这样传递一个参数:

    select_rows('abc')
    

    这样的多个参数:

    select_rows('abc', 'def')
    

    如果你已经有一个列表:

    items = ['abc', 'def']
    select_rows(*items)
    

    【讨论】:

    • +1 喜欢这种方法比 Andrew Hare 的方法更好...问题可能是您需要将更多参数传递给同一个函数,而不仅仅是列表/单个参数。但是您可以在之前使用它们,也可以使用关键字参数,即 **kwargs。
    • 这个答案显然更好。 +1 自记录代码。 *args 请求一个可迭代对象。
    【解决方案3】:

    我会这样做:

    def select_rows(to_select):
        # For a list
        for row in range(0, table.numRows()):
            if _table.item(row, 1).text() in to_select:
                table.selectRow(row)
    

    并期望参数始终是一个列表 - 即使它只是一个元素的列表。

    记住:

    请求原谅比请求许可更容易。

    【讨论】:

    • +1... 只维护一组代码来执行任务要容易得多,而且更 Pythonic;如果有人无视文档,让它爆炸。如果确实需要一个接受单个整数作为参数的函数,请创建第二个名为 'def select_row(to_select)' 的函数并将其打包为列表 'to_select',然后调用 select_rows。
    • @JarretHardie :“如果有人无视文档,就让它爆炸吧” ... 作为 C# 的难民,我发现 Python 编程中的这种态度最令人困惑 :-D
    【解决方案4】:

    我会使用 Sharkey 的版本,但要使用更多的鸭式打字:

    def select_rows(to_select):
        try:
            len(to_select)
        except TypeError:
            to_select = [to_select]
    
        for row in range(0, table.numRows()):
            if _table.item(row, 1).text() in to_select:
                table.selectRow(row)
    

    这有利于使用任何支持 in 运算符的对象。此外,如果给定一个元组或其他序列,以前的版本只会将其包装在一个列表中。缺点是使用异常处理会有一些性能损失。

    【讨论】:

    • 这个对于 unicode 和字符串来说是有问题的。参考:stackoverflow.com/questions/305359/…
    • 有效点,至少应该是“in (list, tuple)” ...或者可能是“not in (string, unicode)”。我想你最好直接寻找“这个东西是否支持'in'”。
    • 实际上,Python 并没有像其他语言那样对异常处理有性能损失。参见,例如:jeffknupp.com/blog/2013/02/06/…
    【解决方案5】:

    一个简单的包装器可以处理列表或单个对象的情况

      def wrap_list(val):
        if type(val) is list:
          return val
        return [val] 
    

    【讨论】:

      【解决方案6】:

      使用 numpy 不太通用但简洁:

      numpy.unique()
      

      通过仅保留类数组或标量的唯一值来自动处理该问题,并返回唯一值或标量的列表。

      import numpy as np
      
      def select_rows(to_select):
         to_select = np.unique(to_select)
      
         for row in range(0, table.numRows()):
             if _table.item(row, 1).text() in to_select:
                 table.selectRow(row)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-22
        • 1970-01-01
        • 2020-05-01
        • 2017-11-28
        • 2021-01-05
        • 1970-01-01
        • 2022-11-13
        相关资源
        最近更新 更多