Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从字典中的键值对跳转以创建循环列表_Python_Loops_Dictionary_Iteration_Key Value - Fatal编程技术网

Python 如何从字典中的键值对跳转以创建循环列表

Python 如何从字典中的键值对跳转以创建循环列表,python,loops,dictionary,iteration,key-value,Python,Loops,Dictionary,Iteration,Key Value,在我的家庭作业中,一个循环被定义为一组键,它们从键->值->键跳转,返回到其原始起始值。例如: d1 = {1:6, 3:1, 6:3} cycles = [[1, 6, 3]] 因为1:6->6:3->3:1,并且起始键==最后一个值 类似地,对于以下词典: d1 = {1: 5, 2: 14, 3: 15, 4: 3, 5: 5, 6: 5, 7: 15, 8: 6, 9: 10, 10: 15, 11: 12, 12: 15, 13: 14, 14: 8, 1

在我的家庭作业中,一个循环被定义为一组键,它们从键->值->键跳转,返回到其原始起始值。例如:

d1 = {1:6, 3:1, 6:3}
cycles = [[1, 6, 3]]
因为1:6->6:3->3:1,并且起始键==最后一个值

类似地,对于以下词典:

d1 = {1: 5, 2: 14, 3: 15, 4: 3, 5: 5, 6: 5, 
      7: 15, 8: 6, 9: 10, 10: 15, 11: 12, 
      12: 15, 13: 14, 14: 8, 15: 9}
正确排序后,映射给出的循环为:
[[5],[9,10,15]]
(也是因为5:5是一个完整的循环,9:10->10:15->15:9) 有没有办法创建一个循环来跟踪字典中的这些循环?我希望创建一行代码,用于任何随机键值字典映射

cycle=[]
For k,v in d1.items():
    if k == v:
        cycle.append([k])

For k,v in mapping2.items
    if k!=v:
        if v in keys:
            start_k = k

If mapping[k] in keys:

这个答案解释了一个潜在的算法,但没有实现它。 如果你想自己找到一个算法,那就停止阅读

也许有更聪明的方法,但有一种方法是。 如果您有一个包含n个键的dict,那么您将需要n次迭代来检测所有可能的周期

让我们调用初始dict d并假设它有N个(大写N个)键/值对

1.)复制一份d cpy=dict(d)

循环长度n=1的初始迭代: 在cpy中查找所有键,其中cpy[key]==key

将这些添加到解决方案列表中,并从复制的dict中删除这些条目

循环长度n=2的第一次迭代: 按以下方式创建新的dict cpy2: 为cp的每个键创建一个val,该val由
d[cp[key]]
现在将cpy2分配给cpy
cpy=cpy2

现在在cpy中查找所有键,其中cpy[key]==key 您知道,对于这些值,您有长度为n的循环,如果需要,可以通过从d开始并迭代n次来重建它们

循环长度n=3的第二次迭代: 遵循第一次迭代中的说明

迭代直到循环长度n==n

使用这种方法,您应该能够识别所有循环。 然而,如果你有一个长度为n的循环,那么同一个循环就有n个解

例如,如果有循环[9,10,15],则会发现: [10,15,9]和[15,10,9]因此,如果循环中的第一个值不是值列表中的最小值,则应排除甚至不存储任何解决方案,这应该有效

#!/usr/bin/env python3

def get_cycles(d):
    cycles = []

    while d:
        # Keep track of keys we've iterated through in this loop
        tracked = []

        # Take the next available key
        k = next(iter(d))

        while True:
            tracked.append(k)

            # This key (the value of the previous key) must have already 
            # been deleted, meaning it was part of a cycle or lead to 
            # repetitions of an already discovered cycle
            try:
                v = d[k]
            except KeyError:
                # Always delete keys leading up to the current key too, as this
                # same loop will happen every time we land on one of these keys
                # otherwise
                for t in tracked:
                    if t in d:
                        del d[t]
                break

            # If the value of the current key was one of the keys leading up to
            # the current key, we've discovered a cycle starting from the value
            # of the current key and ending at the current key
            if v in tracked:
                cycle = tracked[tracked.index(v):]
                cycles.append(cycle)
                for c in cycle:
                    del d[c]
                break

            # If the value of the current key is a key in any of the
            # previously discovered cycles, we want to delete this sequence,
            # as we've already discovered the cycle it leads to
            if any(v in cycle for cycle in cycles):
                for t in tracked:
                    del d[t]
                break

            # Set the next key
            k = v

    return cycles


d1 = {1: 5, 2: 14, 3: 15, 4: 3, 5: 5, 6: 5, 7: 15, 8: 6, 9: 10, 10: 15, 11: 12, 12: 15, 13: 14, 14: 8, 15: 9}
d2 = {1:6, 3:1, 6:3}

print(get_cycles(d1))
print(get_cycles(d2))
输出:

[[5], [15, 9, 10]]
[[1, 6, 3]]
算法跟踪它迭代通过的每个关键点,通过将关键点设置为其自身的值进行迭代

如果某个键的值已在迭代键列表中,则已发现从迭代键列表中该位置到结束的循环。然后,必须从字典中删除导致发现此循环的跟踪密钥,因为此循环已被遍历

如果键的值是先前发现的某个周期中的键,则必须从字典中删除当前遍历键序列,因为该序列所导致的周期已被发现


如果一个键的值不再是键本身(当该键的值被测试为键时会引发一个键错误),循环就会中断,因为该键必须已经被删除,这意味着它是一个周期的一部分或导致一个周期的序列的一部分。

您到底需要什么帮助?你能用简单的英语描述一下你想遵循的算法吗?我想创建一个循环,可以从字典中列出完成一个“循环”的键(因为1:1[1]将是一个循环,而在1:3,3:1中,[1,3]将是一个循环)