Python 根据订单安排项目

Python 根据订单安排项目,python,cycle,reorderlist,Python,Cycle,Reorderlist,我有一个元素列表,我需要周期性地重新排列,以保持它们的顺序。这个问题看起来很简单,但我想不出一个聪明的编码方法。假设你有元素 1 2 3 4 o o o 5 6 7 o在数组中始终是连续的,但我需要更改此数组,以便o(不一定是不同类型的)以循环方式位于最后: 5 6 7 1 2 3 4 o o o 问题是o也可能以循环方式连续。比如说, o o 1 2 3 4 5 6 7 o 有没有一个聪明的方法可以做到这一点?我一直在查看itertools中的cycle,但到目前为止,我还没有一个有效的

我有一个元素列表,我需要周期性地重新排列,以保持它们的顺序。这个问题看起来很简单,但我想不出一个聪明的编码方法。假设你有元素

1 2 3 4 o o o 5 6 7
o在数组中始终是连续的,但我需要更改此数组,以便o(不一定是不同类型的)以循环方式位于最后:

5 6 7 1 2 3 4 o o o
问题是o也可能以循环方式连续。比如说,

o o 1 2 3 4 5 6 7 o
有没有一个聪明的方法可以做到这一点?我一直在查看itertools中的
cycle
,但到目前为止,我还没有一个有效的实现,因为我所做的无法处理最后一个案例

更新

我有一个第一个工作实现:

def arrange2(nodes, contiguous):

    arranged = []
    size = len(nodes)

    if nodes[0] in contiguous:

        # obtain the id of the last interface node in nodes
        id = None
        for i in range(1, len(nodes)):
            if nodes[i] not in contiguous:
                id = i
                break

        # copy nodes to new list starting from the first node past id
        for i in range(id, id + size):
            arranged += [nodes[i % size]]
    else:

        # obtain the id of the last interface node in nodes
        id = None
        for i in range(size - 1, -1, -1):
            if nodes[i] in contiguous:
                id = i
                break

        # copy nodes to new list starting from the first node past id
        for i in range(id+1, id + size+1):
            arranged += [nodes[i % size]]

    return arranged


print(arrange2([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [5, 6]))
这张照片
[7,8,9,10,1,2,3,4,5,6]

好的,根据您的实现,我有以下几点:

def arrange(nodes: list, contigious: list) -> list:
    first_contigious = nodes.index(contigious[0])
    last_contigious = nodes.index(contigious[-1])

    if first_contigious < last_contigious:
        # Normal situation
        return nodes[last_contigious+1:] + nodes[:first_contigious] + contigious
    else:
        # The contigious part is cycling
        return nodes[last_contigious+1:first_contigious] + contigious
def arrange(nodes: list, contigious: set) -> list:
    # Make sure that contigious is a set
    contigious = set(contigious)

    # Return if all nodes are in contigious or nodes are empty
    if len(contigious.intersection(nodes)) == len(nodes) or not len(nodes):
        return nodes

    if nodes[0] in contigious and nodes[-1] in contigious:
        # The contigious part is split and present on the beggining and the 
        # end of the nodes list
        cut = next(i for i, x in enumerate(nodes) if x not in contigious)
        # I move the nodes from the beggining to the end
        return nodes[cut:] + nodes[:cut]
    else:
        # The contigious part is somewhere in the middle of the nodes list
        # I need to find the end of contigious sequence
        cut = next(i for i, x in enumerate(reversed(nodes)) if x in contigious)
        cut = len(nodes) - cut
        return nodes[cut:] + nodes[:cut]

注意:您的工作是确保连续元素确实彼此相邻,并且不分散在3个或更多组中。

利用所有“o”都是连续的这一事实,我实现了:

def rearrange(l):
    i=0
    found=False
    while i<len(l):
        if l[i]=="o":
            found=True
            l=l[i+1:]+l[:i+1]
            i=0
        else:
            if found:
                break
            i+=1
    return l

要提供一个连续元素列表而不是“o”,这个小改动应该有效:

def rearrange(l,contiguous):
    i=0
    found=False
    while i<len(l):
        if l[i] in contiguous:
            ...
def重新排列(l,连续):
i=0
发现=错误

当我看你的更新时,我想我把“o”字看得有点太字面了。有没有一种不那么冗长的方法?另外,看看我给出的例子,我有一个连续的值列表,而你只检查“o”。是的,这似乎是可行的。到目前为止,这是我得到的最好的答案。虽然ID不一定是有序的,但它是唯一的。你能提供更多真实的例子吗?我不明白为什么连续需要是
[5,6]
而不仅仅是6。你可以从这个列表中获取任意一组连续的数字。我以
[5,6]
为例,但您可以以循环方式连续的
[9,10,1,2]
[10,1,2]
等为例。但是“我想要2个结尾”和“我想要10,1,2”结尾有什么区别?如果将2放在末尾,并保留顺序,则末尾将有“10,1,2”。所有相邻元素都需要重新排列,以便它们位于列表的末尾。因此,如果我的连续元素是
[9,10,1,2]
,那么列表应该是
[3,4,5,6,7,8,9,10,1,2]
。如果连续列表是
[10,1,2]
,那么结果将是
[3,4,5,6,7,8,9,10,1,2]
。两个结果完全相同,这证明了我的观点。这失败了:
打印(排列([400259260401],[400401])
@aaragon这是因为
[400401]
不是
的子序列[400,259,260,401,400,259,260,401,…]
。这很好
arrange([400,259,260,401],[401,400])
。我的坏@Maciek,似乎没问题,因为我给出的实际顺序是错误的。这很有效:
打印(arranrange([400,259,260,401],[401,400])
打印
[259,260,401]400]
这是正确的。这也会中断:
打印(排列([4,1,2,5],[4,5])
。问题是您传递的连续数组可能没有顺序。因此在本例中,当您传递连续的as
[5,4]
而不是as
[4,5]时,它会起作用
在这两种情况下都应该有效。哦,第二个参数应该是一个
set
以避免混淆任何人:)好的,让我看看如何修复它。。。
def rearrange(l,contiguous):
    i=0
    found=False
    while i<len(l):
        if l[i] in contiguous:
            ...