【问题标题】:Generator object to produce kwargs mapping for function生成器对象为函数生成 kwargs 映射
【发布时间】:2017-07-28 16:26:04
【问题描述】:

我有一个通用的生成器函数,它将分隔字符串映射到从分隔字符串列表中生成 kwargs 类型字典对象的 a。

我想在另一个生成器函数中使用 kwargs 类型的字典作为参数。但是,我收到了消息

** 后面的edge_generator() 参数必须是映射,而不是生成器

这是我当前的损坏代码:

def line_from_file_generator(file_name):

    with open(file_name) as text_file:
        for line in text_file:
            yield line

def map_delimited_lines_to_kwargs(lines, delimiter, kwarg_index_map):

    for line in lines:

        kwargs = {}
        args = line.strip().split(delimiter)

        for kwarg, index in kwarg_index_map.items():
            kwargs[kwarg] = args[index]

        yield kwargs


def edge_generator(source_node_name, destination_node_name, weights):

    for line in lines:
        yield Edge(source_node_name, destination_node_name, weights)


lines = line_from_file_generator('mit_map.txt')
kwarg_index_map = {'source_node_name': 0, 'destination_node_name': 1, 'weights': 2}
kwarg_collection = map_delimited_lines_to_kwargs(lines, ' ', kwarg_index_map)
edges = edge_generator(**kwargs_collection)

我现在明白为什么这是错误的了(生成器是一种序列,而不是映射(可以扩展的字典))。

我可以在保留我创建的抽象的同时解决这个问题吗?代码是什么?我尝试将最后一行更改为以下内容,但它无法遍历 kwargs 生成器,并且所有边都是使用相同的参数生成的。

edges = edge_generator(**kwarg_collection.next())

【问题讨论】:

  • 乍一看,您的map_delimited_lines_to_kwargs() 应该只是在循环之后返回一个单独的kwargs dict(当然,在循环之前对其进行初始化),而不是产生一个每次循环。
  • @jasonharper - 是的,我认为你是对的。这大大简化了事情!我想我在生成器功能上做得太过火了。这是我第一次使用它们...
  • @jasonharper,说,我确实失去了使用生成器的好处,当使用边然后构建图形时,因为我必须提前实现所有的 kwargs 来生成边.我找到了另一种方法来做到这一点,但是我将作为答案发布

标签: python dictionary generator keyword-argument


【解决方案1】:

这就是我让它工作的方式。我没有尝试在函数定义中扩展 Edge 生成器的参数,而是简单地传递了整个 kwargs 生成器,并在 Edge 生成器的主体中在 kwargs 生成器上添加了一个循环,并在创建边缘时扩展了参数。

def line_from_file_generator(file_name):

    with open(file_name) as text_file:
        for line in text_file:
            yield line


def kwargs_from_delimited_strings_generator(lines, delimiter, kwarg_index_map):

    for line in lines:

        kwargs = {}
        args = line.strip().split(delimiter)

        for kwarg, index in kwarg_index_map.items():
            kwargs[kwarg] = args[index]

        yield kwargs


def edge_generator(kwargs_collection):

    for kwargs in kwargs_collection:
        yield Edge(**kwargs)


lines_from_file = line_from_file_generator('mit_map.txt')
kwarg_index_map = {'source_node_name': 0, 'destination_node_name': 1,
                   'weights': 2}
kwargs_from_delimited_strings = kwargs_from_delimited_strings_generator(
                                    lines_from_file, ' ', kwarg_index_map)
edges_from_kwargs = edge_generator(kwargs_from_delimited_strings)

【讨论】:

    【解决方案2】:

    以下是我可能会如何修改您的程序。

    请注意,我尽可能长时间地延迟使用 ** 运算符。事实上,在我有一个具体的dict 之前,我不会使用它。

    请注意,edge_generator 迭代其参数,而不是 lines。无论如何,我不确定lines 应该来自哪里。

    请注意,生成器链被保留。在将list() 构造函数应用于最终生成器之前,不会构造完整的边集。

    def Edge(source_node_name, destination_node_name, weights):
        '''Testing version of Edge()'''
        return '{}/{}/{}'.format(source_node_name, destination_node_name, weights)
    
    def line_from_file_generator(file_name):
        with open(file_name) as text_file:
            for line in text_file:
                yield line
    
    def map_delimited_lines_to_kwargs(lines, delimiter, kwarg_index_map):
        for line in lines:
            kwargs = {}
            args = line.strip().split(delimiter)
    
            for kwarg, index in kwarg_index_map.items():
                kwargs[kwarg] = args[index]
    
            yield kwargs
    
    def edge_generator(edge_attribute_dicts):
        for attribute_dict in edge_attribute_dicts:
            yield Edge(**attribute_dict)
    
    lines = line_from_file_generator('mit_map.txt')
    kwarg_index_map = {
        'source_node_name': 0,
        'destination_node_name': 1,
        'weights': 2}
    kwargs_collection = map_delimited_lines_to_kwargs(lines, ' ', kwarg_index_map)
    edges = edge_generator(kwargs_collection)
    print(list(edges))
    

    【讨论】:

      猜你喜欢
      • 2011-02-19
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 2018-02-09
      • 1970-01-01
      • 2016-12-02
      • 1970-01-01
      • 2018-06-18
      相关资源
      最近更新 更多