【问题标题】:Stop Python enumerate() from splitting a string into characters阻止 Python enumerate() 将字符串拆分为字符
【发布时间】:2019-10-02 11:17:23
【问题描述】:

我有一个函数,它接受关键字参数列表并根据关键字列表计算一堆结果,我正在使用 enumerate 来构造循环,以便输出包含所有结果的数据表。当参数列表大于一个但只传递一个参数时,一切都很好,枚举认为它想将该关键字拆分为单个字母。解决此问题的明显方法是只删除 enumerate 调用并使用计数器变量,但有什么方法可以使用 enumerate 函数来禁止这种行为?

下面是示例代码:

import numpy as np
import pandas as pd

x=np.array([1,2,3,4,5])

params = ("x**2","x**3","x**4")

chars = {
   "x**2": lambda x: x**2,
   "x**3": lambda x: x**3,
   "x**4": lambda x: x**4
}

Matrix, names = np.zeros((x.shape[0], len(params)+1)), ["x"]
Matrix[:,0] = x[:]
for counter, param in enumerate(params, start=1):
    Matrix[:,counter] = chars[param](x)
    names.append(param)

panda_matrix = pd.DataFrame(Matrix)
panda_matrix.columns = names

print(panda_matrix)

就像我说的,当有多个参数可供枚举时,我得到了我想要的:

但是当我只传递一个参数时,枚举认为它想把它分成一堆单独的字符。

Traceback (most recent call last):
  File "C:\Users\1mike\PycharmProjects\libRL\example.py", line 41, in <module>
    Matrix[:,counter] = chars[param](x)
KeyError: 'x'

Process finished with exit code 1

有什么办法吗?

【问题讨论】:

  • 做一些类型检查。如果 params 不是元组,则将其变为一个。
  • 那行得通。虽然我一直在玩它,发现如果用户输入参数,例如 ['x'] 或 {'x'} 而不是 ('x'),那么 python 会正确解释它。感谢您为我指明正确的方向!

标签: python pandas numpy enumerate


【解决方案1】:

正如您所发现的,('x') 看起来可能是一个元组,但事实并非如此。 ('x',) 是一个元组,'x', 是一个元组……但期望你的用户知道这似乎是不合理的。

将事物转换为元组的建议很好,但要小心:tuple('ab')('a', 'b'),所以你又回到了原点。但是你可以检查params是否是带有isinstance(params, str)的字符串,如果是则处理:

if isinstance(params, str):
    params = (params,)

还有另一种方法,但它可能会更好,也可能不会更好。 NumPy 有一个方便的函数atleast_1d(),它检查一个数组是否至少有一个维度。也许在这里有点矫枉过正,但很高兴知道:

>>> import numpy as np
>>> np.atleast_1d('x**2')
array(['x**2'], dtype='<U4')

您始终可以使用 tuple() 将其转换回元组。

【讨论】:

  • 我不确定我是否会推荐类型嗅探部分。 paramsstr 值的可迭代对象,因此 params = ('x**2',) 将是首选解决方案。
  • 好的,但是如果你有 'x**2' 开头...我同意检查类型并不是 Python 式的,但有时我们想要灵活一些,例如许多 NumPy 和 SciPy 函数处理标量或 ndarray。
  • 检查类型不是 Pythonic?我绝对不同意。当类型检查和类型化参数被引入核心时,还有什么大惊小怪的?
  • 大惊小怪是我的意思。我不会在这里卷入宗教战争——只是想帮助别人。要么接受,要么离开。
  • 我明白你们都在说什么,但仅从用户体验来看,我不知道在单个输入参数之后需要逗号还是只要求用户使用列表会更奇怪或设置为输入。这里的目标是 params 是一个函数参数,例如 def func(x, y, params={"x **2","x **3","x **4"}, **kwargs) 所以用户可以通过字典“chars”选择他们想要激活的 lambdas。
猜你喜欢
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2012-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 2019-04-16
相关资源
最近更新 更多