python - 如何在不同长度的列表上使用 map(),用自定义值填充最短的列表
问题描述
我想使用地图在多个列表上应用一个函数,并用自定义值填充最短的列表。我已经使用 for 循环和 zip_longest 创建了一个解决方案,但我认为可以使用map()
. 我不知道哪个列表最长,它们可能具有相同的长度。这是我的实现:
import itertools
items1 = [1, 2, 3, 4]
items2 = [1, 2]
items3 = [1, 1, 1]
def multiply(a, b, c):
if a is None:
a = 0.5 # custom value, could also be set elsewhere
if b is None:
b = 0.4
if c is None:
c = 0.3
return a * b * c
squared_numbers = []
for numbers in itertools.zip_longest(items1, items2, items3):
squared_numbers.append(multiply(*numbers))
的价值squared_numbers
:
[1, 4, 1.2000000000000002, 0.48]
奖励:我更喜欢通过 设置自定义值def multiply(a=5, b=0.4, c=0.3)
,但我不确定这是否可行。
编辑:代码工作正常,我只是好奇它是否可以进一步优化。
解决方案
也许你的意思是itertools.starmap
而不是map
?这是我想出的东西,但我不会说它比你已经写的更好:
from itertools import zip_longest, starmap
lists = [
[1, 2, 3, 4],
[1, 2],
[1, 1, 1]
]
def multiply(*args):
from functools import reduce
from operator import mul
defaults = [0.5, 0.4, 0.3]
return reduce(mul, (arg or default for arg, default in zip(args, defaults)))
squared_numbers = list(starmap(multiply, zip_longest(*lists)))
print(squared_numbers)
输出:
[1, 4, 1.2000000000000002, 0.48]
>>>
如果您正在使用itertools.zip_longest
,则无法真正绕过使用fillvalue
- 在我们的例子中,这意味着我们将始终将三个参数传递给multiply
,即使它们全部或其中一些是None
(itertools.zip_longest
的默认值fillvalue
)。这意味着您不能使用默认的位置参数,因为它们只有在没有足够的位置参数传入时才会生效,而永远不会出现这种情况。
中的生成器表达式functools.reduce
通过短路评估工作。该表达式arg or default
将评估arg
是否arg
为真,default
否则。None
被认为是错误的,因此如果arg
是None
,则表达式的计算结果为default
。
推荐阅读
- python - 升级到 PyTorch 1.9 ImportError 时的潜在错误:无法从“torch._six”导入名称“int_classes”
- php - 控制器中的静态或Where条件
- c - 读取 hexdump,fread
- python - 我可以在布局中包含的小部件中使用选项卡控件吗?
- json - 从递归目录树遍历构建 JSON 对象
- mysql - SQL 选择语句没有产生正确的结果
- r - 使用库时出错(tidyverse)
- javascript - 事件处理程序节流或延迟(去抖动)的特定于侦听器的超时变量?
- javascript - 简化 javascript 颜色更改功能
- django - 将图像保存在 django 模板中