根据订单安排项目

2024-06-02 09:03:07 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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]


Tags: the方法inidnode元素forsize
2条回答

利用所有“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

您可以遍历列表。在第一次出现i一个“o”时,您可以拆分列表并反转它。 l=["o","o",1,2,3,"o"]["o"] (l[:i+1])["o",1,2,3,"o"] (l[i+1:])中被“拆分”。把这两部分颠倒过来,再把它们放在一起,就得到了一个新的列表["o",1,2,3,"o","o"]
这样,“o”就被推到了最后。你知道吗

然后从新列表开始。当新列表不是以“o”开头时(found为True,l[i]!="o"),表示您的任务完成了。你知道吗

>>>l=[1,2,3,4,"o","o","o",5,6,7]
>>>print(rearrange(l))
[5, 6, 7, 1, 2, 3, 4, 'o', 'o', 'o']


>>>l=["o","o",1,2,3,"o"]
>>>print(rearrange(l))
[1, 2, 3, 'o', 'o', 'o']

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

def rearrange(l,contiguous):
    i=0
    found=False
    while i<len(l):
        if l[i] in contiguous:
            ...

好的,根据你的执行情况,我有:

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个或更多组。你知道吗

相关问题 更多 >