【问题标题】:How do I iterate over *args when passing a list? [closed]传递列表时如何迭代 *args? [关闭]
【发布时间】:2021-08-25 09:22:40
【问题描述】:

我编写了以下函数,它将数据帧的任意数量的列作为一个列表,然后打印指定列的中位数:

def calculate_median(dataframe, *args, *kwargs):
    print("Median of columns: ")
    for colname in args or kwargs.values():
        median_of_column = np.median(dataframe[colname])
        print(f"{median_of_column}", sep="\n")
    return colname

所以,如果我在数据框中有以下列列表:

colnames = ['Col A', 'Col B', 'Col C', 'Col D']

我遇到的问题是解释器将 整个 列表作为一个整体参数并显示 第一列 (Col A) 的中位数。

我不确定我做错了什么。你能帮忙吗?

【问题讨论】:

  • 你怎么称呼这个?
  • @interjay - median_of_df_columns = calculate_median(df, colnames) # df has been imported before
  • 你为什么使用可变参数 (*args) 而不是普通参数?您对kwargs 的使用似乎也是错误的。
  • 在参数中使用 *args 并不意味着 Python 会解包传递给它的参数。这只意味着它会pack 收到的参数。如果要将列表解压缩为参数,请在调用中使用 *。如果您只想解包然后再次打包,只需完全跳过解包/打包并将其作为普通参数/参数传递/接收。

标签: python python-3.x list function statistics


【解决方案1】:

如果你这样调用你的函数:

df = ...
colname = calculate_median(df, colnames)

你需要这样称呼它:

df = ...
colname = calculate_median(df, *colnames)

*args 参数表示“任意数量的非关键字(即未命名)参数”。如果您只是传递一个列表 (colnames),那是一个参数,而不是多个参数。传递*colnames 意味着“解压此列表并将其中的项目用作参数”。

【讨论】:

    【解决方案2】:

    首先,您在*kwargs 上缺少一个星号。你的函数签名应该是:

    def calculate_mean(dataframe, *args, **kwargs):
    

    其次,我不确定您的 for 循环是否按照您的想法执行。目前它将遍历args,并且仅在args 为None 或为空的情况下遍历kwargs.values()。如果您想始终对两者进行迭代,您可以将 kwargs.values() 转换为元组,使其具有与 args 相同的类型,然后将它们连接起来:

    for colname in args + tuple(kwargs.values()):
    

    然后你会这样调用你的函数:

    calculate_mean('Col A', 'Col B', 'Col C', 'Col D')
    

    或者如果你有一个列表:

    colnames = ['Col A', 'Col B', 'Col C', 'Col D']
    

    如果你想以列表的每个成员作为参数来调用函数,你需要在调用函数时使用星号解包列表:

    calculate_mean(*colnames)
    

    【讨论】:

    • 我看不到迭代 kwargs.values 的价值,而首先忽略了键。
    • @interjay 我也没有,但据我了解,这就是 OP 想要做的。
    • 我认为 OP 并不确切知道他们想要做什么。他们可能不明白**kwargs 做了什么。这不是对您的回答的批评,因为在 OP 澄清之前没有什么可以做的。
    • @interjay 是的,再次阅读问题后,我怀疑您是对的。
    【解决方案3】:

    您需要将*df.columns 作为*args 参数传递以获得所需的结果。因为只传递df.columns 不会解压列的值。

    我不明白你为什么需要*kwargs 参数。

    【讨论】:

      【解决方案4】:
      import numpy as np
      import pandas as pd
      
      df = pd.DataFrame({"a": [1, 2, 3, 4, 5], "b": [11, 22, 33, 44, 55], "c": [111, 222, 333, 444, 555]})
      print(df)
      
      # error: need double *
      def calculate_median(dataframe, *args, **kwargs):
          print("Median of columns: ")
          for colname in args or kwargs.values():
              median_of_column = np.median(dataframe[colname])
              print(f"{median_of_column}", sep="\n")
          return colname
      # get dataframe column names 
      colnames= df.columns.values
      print(f"colnames type={type(colnames)}")
      print(f"colnames values={colnames}")
      # call function
      calculate_median(df, *colnames)
      

      【讨论】:

      • 如果你解释一下你改变了什么以及为什么会有所帮助,而不是让我们玩“找出差异”。
      猜你喜欢
      • 1970-01-01
      • 2014-03-17
      • 2011-11-04
      • 1970-01-01
      • 2021-02-14
      • 1970-01-01
      • 1970-01-01
      • 2021-03-11
      • 1970-01-01
      相关资源
      最近更新 更多