【转帖】argument after ** must be a mapping, not list

本文解决了一个使用Python格式化字符串的问题,介绍了如何通过遍历字典列表并应用字符串格式化方法来创建新的字符串列表。提供了两种解决方案,一种使用范围迭代,另一种直接遍历列表元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:https://teamtreehouse.com/community/format-argument-after-must-be-a-mapping-not-list

问题:

Create a function named string_factory that accepts a list of dictionaries and a string. Return a new list build by using .format() on the string, filled in by each of the dictionaries in the list.

Here's my code: Please help!

dicts = [
    {'name': 'Michelangelo',
     'food': 'PIZZA'},
    {'name': 'Garfield',
     'food': 'lasanga'},
    {'name': 'Walter',
     'food': 'pancakes'},
    {'name': 'Galactus',
     'food': 'worlds'}
]

string = "Hi, I'm {name} and I love to eat {food}!"

def string_factory(dicts, string):
  strings = []
  for items in dicts:
   string.format(**dicts) 
  return strings

print(string_factory(dicts, string))

方案:

Here you can see 2 possible ways of doing it:

First:

def string_factory(dictionary, strings):
  string_list = []
  for i in range(len(dictionary)):
    string_list.append(strings.format(**dictionary[i]))

  return string_list

Second:

def string_factory(dictionary, strings):
  string_list = []
  for element in dictionary:
    string_list.append(strings.format(**element))

  return string_list

采纳:

def string_factory(dicts, string):

  formatted = []
  for data in dicts:
    new_dict = data
    formatted.append(string.format(**new_dict))
  return formatted


print(string_factory(dicts, string))

<think>我们正在解决一个编程错误:TypeError:generate()argumentafter**mustbeamapping,notTensor。根据引用[1]和引用[2],这个错误通常是因为在函数调用中使用`**`解包时,传入的对象不是一个字典(mapping)而是一个Tensor(或字符串等其他类型)导致的。具体到我们的问题,是在调用`transformers.generation.utils.GenerationMixin.generate()`方法时,某个参数应该是一个字典,但我们传入了一个Tensor。引用[3]提供了模型输入处理的部分源码,其中提到模型输入需要是tensor,但同时也需要处理关键字参数(model_kwargs)为映射(字典)。这提示我们在调用generate方法时,需要确保传递给`**model_kwargs`的是一个字典。解决方案步骤:1.检查调用generate方法时传入的参数,特别是使用`**`解包的部分。2.确保解包的对象是一个字典(mapping),而不是Tensor或其他类型。常见错误场景:-可能将输入数据的tensor直接作为关键字参数传递,但实际上应该放在位置参数中,而关键字参数应该是字典形式。-可能误将模型的其他输出(如tensor)作为关键字参数传递。修正方法:假设我们原本的调用可能是这样的:```pythonoutput=model.generate(input_ids,**some_tensor)```正确的做法应该是将输入tensor作为位置参数,而关键字参数需要是字典。例如:```pythonoutput=model.generate(input_ids,attention_mask=attention_mask,...)```或者如果使用字典来传递关键字参数,那么确保这个字典是键值对映射:```pythonmodel_kwargs={'attention_mask':attention_mask,...}output=model.generate(input_ids,**model_kwargs)```特别注意:在准备输入时,要区分位置参数和关键字参数。输入tensor(如input_ids)通常是位置参数,而其他配置参数(如attention_mask,decoder_input_ids等)应该以关键字参数形式传递,或者打包成字典再用`**`解包。如果错误出现在自己封装的代码中,检查传递给generate的`**model_kwargs`变量,确保它是一个字典。如果它变成了一个tensor,那么需要回溯检查赋值过程。例如,在引用[3]的代码中,模型输入处理部分会从`model_kwargs`中提取信息,并确保`inputs_tensor`是张量,而`model_kwargs`仍然是字典。因此,在调用`_prepare_model_inputs`方法后,`model_kwargs`应该被正确处理。如果问题仍然存在,请检查是否在代码中意外修改了`model_kwargs`,例如将其赋值为一个张量。总结:确保传递给generate方法的关键字参数解包(**后面的变量)是一个字典,而不是张量。</think>### TypeError: generate() argument after ** must be a mapping, not Tensor 解决方案 这个错误发生在调用Hugging Face Transformers库的`generate()`方法时,传递的关键字参数不符合要求。根本原因是**传递给`**`解包操作符的参数必须是字典(mapping),但你传递了一个Tensor对象**。以下是详细解决方案: #### 错误原因分析 1. **语法规则**Python中`**`操作符要求解包对象必须是键值对映射(如`dict`) 2. **常见场景**: - 误将模型输出张量作为关键字参数传递 - 数据处理环节错误地将张量赋值给关键字参数字典 - 混淆了位置参数和关键字参数的传递方式 #### 解决方案步骤 1. **检查generate()调用**: ```python # 错误示例(传递了Tensor) outputs = model.generate(**input_tensor) # ❌ 触发错误 # 正确写法(字典解包) model_kwargs = {"input_ids": input_ids, "attention_mask": attention_mask} outputs = model.generate(**model_kwargs) # ✅ ``` 2. **验证参数类型**: 在调用前添加类型检查: ```python assert isinstance(model_kwargs, dict), "model_kwargs must be a dictionary" ``` 3. **转换张量为字典**: 如果参数来自预处理结果,参考[^3]的输入处理逻辑: ```python # 正确构建model_kwargs(示例) model_kwargs = { "input_ids": tokenizer.encode(text, return_tensors="pt"), "attention_mask": torch.ones_like(input_ids) } ``` 4. **排查自定义代码**: - 检查`_prepare_model_inputs()`等预处理方法是否返回字典 - 确保没有意外将张量赋值给字典变量: ```python # 错误示例 model_kwargs = inputs_tensor # ❌ 直接赋值张量 # 正确示例 model_kwargs = {"inputs_embeds": inputs_tensor} # ✅ ``` #### 完整修正案例 ```python from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained("gpt2") tokenizer = AutoTokenizer.from_pretrained("gpt2") text = "Hello, how are you?" inputs = tokenizer(text, return_tensors="pt") # 返回字典 # 正确调用(解包字典) outputs = model.generate(**inputs) # ✅ # 错误调用模拟(触发相同错误) try: outputs = model.generate(**inputs["input_ids"]) # ❌ 传递张量 except TypeError as e: print(f"Caught error: {e}") # 重现错误 ``` #### 关键注意事项 1. **输入格式**:使用tokenizer返回的字典直接作为参数 2. **参数检查**:调用前用`type(model_kwargs)`确认对象类型 3. **文档参考**:查阅[Transformers官方文档](https://huggingface.co/docs/transformers/main_classes/model)确认API要求 > 该错误通常源于数据处理流程中的类型混淆,通过严格区分张量和参数字典即可解决[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值