简体   繁体   English

根据 dict 给定的依赖关系,用序列迭代列表

[英]Iterate over list with sequence according to given dependencies from dict

I have a list lst and I want to iteratively transform each element in the list using a function f :我有一个列表lst ,我想使用 function f迭代地转换列表中的每个元素:

lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

def f(x):
    # do something
    return x

I can iteratively apply this transformation over the list:我可以在列表上迭代地应用这个转换:

new_lst = [f(x) for x in lst]

So far so good.到目前为止,一切都很好。 Now we want to introduce sequencing for processing elements in the lst .现在我们要在lst中引入处理元素的排序。 The dict ensure_transformed describes a list of elements that need to be transformed before processing a given element: dict ensure_transformed描述了在处理给定元素之前需要转换的元素列表:

ensure_transformed = {'a' : ['b', 'e'],
                      'b' : ['e', 'f'],
                      'c' : ['a', 'd'],
                      'd' : [],
                      'e' : [],
                      'f' : []
                      }

The interpretation is - Before transforming a , transform b and e , before transforming b , transform e and f and so on.解释是 - 在变换a之前,变换be ,在变换b之前,变换ef等等。

(The meaning of 'd': [] is that no elements need to be processed before d . g is absent from ensure_transformed implying g shouldn't be transformed.) 'd': []的含义是在d之前不需要处理任何元素。 ensure_transformed中不存在g意味着不应该转换g 。)

How can I transform lst using function f while ensuring sequencing from ensure_transformed ?如何在确保从ensure_transformed排序的同时使用 function f转换lst

Options on the table:桌上选项:

  1. Use recursion to go through list while keeping track of elements that have already been transformed.通过列表使用递归到 go,同时跟踪已经转换的元素。 This approach has become messy to manage.这种方法管理起来很麻烦。

  2. Re-order the list using the dict and then iterate over the list.使用 dict 重新排序列表,然后遍历列表。 I haven't tried this approach yet, but it seems promising.我还没有尝试过这种方法,但它似乎很有希望。

I'm open to other approaches.我对其他方法持开放态度。

The ensure_transformed dictionary describes a directed graph where {'a': ['b', 'e']} means that there is an edge b → a and an edge e → a . ensure_transformed字典描述了一个有向图,其中{'a': ['b', 'e']}表示存在边b → a和边e → a

Assuming that the graph has no cycles, your task is equivalent to applying topological sorting to it, for which you can find various algorithms.假设该图没有环,您的任务相当于对其应用拓扑排序,您可以找到各种算法。

As mentioned by @CristianCiupitu in the comments, this is now very easy to do with Python 3.9 by using thegraphlib module:正如@CristianCiupitu 在评论中提到的那样,现在使用graphlib模块很容易用Python 3.9 完成:

import graphlib
lst = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

def f(x): return x.upper() #for example

ensure_transformed = {'a' : ['b', 'e'],
                      'b' : ['e', 'f'],
                      'c' : ['a', 'd'],
                      'd' : [],
                      'e' : [],
                      'f' : []
                      }

ts = graphlib.TopologicalSorter(ensure_transformed)

processed = [f(x) for x in ts.static_order()]
print(processed)
#prints ['E', 'F', 'D', 'B', 'A', 'C']

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM