2017-07-28 37 views
0

我有一个广义生成器函数,它将分隔字符串映射到从分隔字符串列表中产生kwargs类型的字典对象。为函数生成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) 

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

我可以绕过这个,同时保持我创建的抽象?代码是什么?我试过把最后一行改为下面的代码,但是它不能遍历kwargs生成器,并且所有的边都是用相同的参数生成的。

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

+0

乍一看,你的'map_delimited_lines_to_kwargs()'应该简单*收益*单kwargs字典的循环之后(和循环之前进行初始化,当然),而不是通过每一次循环中产生一个。 – jasonharper

+0

@jasonharper - 是的,我认为你是对的。这简化了很多事情!我想我用发电机功能过度了。这是我第一次使用它们...... – Jinglesting

+0

@jasonharper,说,当使用边缘然后建立一个图形时,我确实丧失了使用生成器的好处,因为我必须实现所有的kwargs来生成边缘的时间。我找到了另一种方法来做到这一点,我将作为答案发布 – Jinglesting

回答

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) 
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))