按照顺序排列物品
arrange items respecting order
我有一个元素列表,我需要循环重新排列它们以保持它们的顺序。这个问题看起来很简单,但我想不出一个聪明的方法来编码它。假设你有元素
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" 第一次出现 i
时,您拆分列表并反转它。
l=["o","o",1,2,3,"o"]
在 ["o"] (l[:i+1])
和 ["o",1,2,3,"o"] (l[i+1:])
中是 "split"。将两部分反转并放回原处,得到一个新列表 ["o",1,2,3,"o","o"]
.
这样, "o" 被推到最后。
然后您使用新列表重新开始。如果新列表不是以 'o' 开头(found
为真且 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:
...
我有一个元素列表,我需要循环重新排列它们以保持它们的顺序。这个问题看起来很简单,但我想不出一个聪明的方法来编码它。假设你有元素
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" 第一次出现 i
时,您拆分列表并反转它。
l=["o","o",1,2,3,"o"]
在 ["o"] (l[:i+1])
和 ["o",1,2,3,"o"] (l[i+1:])
中是 "split"。将两部分反转并放回原处,得到一个新列表 ["o",1,2,3,"o","o"]
.
这样, "o" 被推到最后。
然后您使用新列表重新开始。如果新列表不是以 'o' 开头(found
为真且 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:
...