简体   繁体   English

使用python从字典中提取客户端服务器的顺序

[英]Extracting order of client server from a dictionary using python

I have a dictionary like below which for example, for the first item means 5 is the customer of 2. and in the last item, as you can see, 2 is the customer of 4 and 4 is also the customer of item 3. 我有一个像下面这样的字典,例如,对于第一个项目,意味着5是2的客户。在最后一个项目中,如您所见,2是4的客户,而4也是项目3的客户。

customer_provider_dic= {'2':['5'],'1':['2'],'3':['4'],'4':['2']}

I am trying to extract all chains of customer of these items. 我正在尝试提取这些项目的所有客户链。 The output will be like this: 输出将如下所示:

[2,5]
[1,2,5]
[3,4,2,5]
[4,2,5]

I really confused how can I extracts these chains. 我真的很困惑如何提取这些链。 Any suggestion for the flowchart or the steps I should follow. 关于流程图或步骤的任何建议。

First, here's a solution that works if all the lists contain exactly one item. 首先,如果所有列表中都包含一个项目,那么这是一个可行的解决方案。

def simple_chain(graph, key):
    chain = [key]
    while True:
        lst = graph.get(key)
        if lst is None:
            # There's nothing left to add to the chain
            break
        key = lst[0]
        if key in chain:
            # We've found a loop
            break
        chain.append(key)
    return chain

customer_provider = {
    '2': ['5'], '1': ['2'], '3': ['4'], '4': ['2'],
}

data = customer_provider
for k in data:
    print(simple_chain(data, k))

output 输出

['2', '5']
['1', '2', '5']
['3', '4', '2', '5']
['4', '2', '5']

The general solution is a little harder. 一般的解决方案要难一些。 We can create all the chains using a recursive generator. 我们可以使用递归生成器创建所有链。 The code below works, but it's not very efficient, since it makes the same sub-chains multiple times. 下面的代码可以工作,但是效率不高,因为它多次创建相同的子链。

The basic strategy is similar to the previous version, but we need to loop over all the keys in each list, and make a new chain for each one. 基本策略与以前的版本相似,但是我们需要遍历每个列表中的所有键,并为每个列表创建新的链。

To fully understand how this code works you need to be familiar with recursion and with Python generators . 要完全理解此代码的工作方式,您需要熟悉递归和Python 生成器 You may also find this page helpful: Understanding Generators in Python ; 您可能还会发现此页面有帮助: 了解Python中的生成器 there are also various Python generators tutorials available online. 在线上也有各种Python生成器教程。

def make_chains(graph, key, chain):
    ''' Generate all chains in graph that start at key.
        Stop a chain when graph[key] doesn't exist, or if
        a loop is encountered.
    '''
    lst = graph.get(key)
    if lst is None:
        yield chain
        return
    for k in lst:
        if k in chain:
            # End this chain here because there's a loop
            yield chain
        else:
            # Add k to the end of this chain and
            # recurse to continue the chain
            yield from make_chains(graph, k, chain + [k])

customer_provider = {
    '2': ['5'], '1': ['2'], '3': ['4'], '4': ['2'],
}

pm_data = {
    '2': ['5'], '1': ['2'], '3': ['4', '6'], 
    '4': ['2'], '6': ['1', '5'],
}

#data = customer_provider
data = pm_data

for k in data:
    for chain in make_chains(data, k, [k]):
        print(chain)

If we run that code with data = customer_provider it produces the same output as the previous version. 如果我们使用data = customer_provider运行该代码,它将产生与先前版本相同的输出。 Here's the output when run with data = pm_data . 这是使用data = pm_data运行时的输出。

['2', '5']
['1', '2', '5']
['3', '4', '2', '5']
['3', '6', '1', '2', '5']
['3', '6', '5']
['4', '2', '5']
['6', '1', '2', '5']
['6', '5']

The yield from syntax is a Python 3 feature. 语法的yield from是Python 3的功能。 To run this code on Python 2, change 要在Python 2上运行此代码,请更改

yield from make_chains(graph, k, chain + [k])

to

for ch in make_chains(graph, k, chain + [k]):
    yield ch 

Prior to Python 3.6 dict does not retain the insertion order of keys, so for k in data can loop over the keys of data in any order. 之前PYTHON 3.6 dict不保留键的插入顺序,所以for k in data可以在的键环data以任何顺序。 The output lists will still be correct, though. 输出列表仍然是正确的。 You may wish to replace that loop with 您可能希望将该循环替换为

for k in sorted(data):

to get the chains in order. 使链条井然有序。

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

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