Generator对象生成函数的kwargs映射

时间:2017-07-28 16:26:04

标签: python dictionary generator kwargs

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

我想在另一个生成器函数中使用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)

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

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

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

2 个答案:

答案 0 :(得分:0)

这就是我开始工作的方式。我没有尝试在函数定义中扩展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)

答案 1 :(得分:0)

以下是我修改程序的方法。

请注意,我会尽可能延迟使用**运算符。事实上,在我有一个具体的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))