在不使用 *(星号)的情况下解压

Unpack without using * (asterisk)

如果我想保持功能,不想在中间使用*,那么等效的替代功能是什么? 例如,

import operator as op
print(op.eq(*map(str.upper, ['a', 'A'])))

如何避免在此处使用 *

我创建了一个函数,例如,

def unpack(args):
  return *args

但它给出语法错误,print(*args) 有效但 return 失败

functools.reduce 可用于将两个参数的函数累积应用于可迭代对象,这适用于您的示例案例

import operator as op
from functools import reduce
print(reduce(op.eq, map(str.upper, ['a', 'A'])))

您可以使用 reduce 检查所有映射元素是否彼此相等。

from functools import reduce
print(reduce(op.eq, map(str.upper, ['a', 'A'])))

不过,这并不是一件明智的事情。我这样说是因为上面的 reduce 调用并没有推广到具有更多或更少元素的情况:

  • 如果输入为空,它将失败并显示 TypeError: reduce() of empty sequence with no initial value
  • 如果给它一个 one-item 输入列表,它将 return 一个字符串而不是布尔值 TrueFalse.
  • 如果给它一个包含 3 个以上项目的列表,它最终会将字符串与布尔值进行比较,并且总是会得到 False.

如果您的计划是用恰好两个操作数调用 op.eq,不多也不少,那么用 * 解包是合适的。即使在功能上下文中。

实现此目的的一种方法是创建一个名为 apply.

的函数
def apply(func, args):
    return func(*args)
apply(op.eq, map(str.upper, ['a', 'A']))

如果有一些您知道不会发生的安全值,您可以使用 reduce 解决此问题。例如,如果您知道 None 不会出现在您的列表中,您可以执行

import functools
mylist = list(map(str.upper, ['a', 'A']))
result = functools.reduce(lambda x, y: x if x == y else None, mylist)
print('all equal' if result != None else 'some differ')