2017-07-28 73 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))