Python 高级列表理解
每次将INT列表输入程序1,例如:Python 高级列表理解,python,list-manipulation,Python,List Manipulation,每次将INT列表输入程序1,例如: [1, 3, 1, 4, 4, 3, 1] 任务: 打印包含与给定列表完全相同的数字的列表, 但是重新排列,使每3后面紧跟着一个4。3不能移动索引位置,但每隔一个数字可以移动一次 示例的输出应为: [1, 3, 4, 1, 1, 3, 4] 到目前为止,我的代码只能完成规则1和2。如何修改我的代码以适应这种情况 newList=[] n=0 numCount= int(input()) while True: try: n =
[1, 3, 1, 4, 4, 3, 1]
任务:
打印包含与给定列表完全相同的数字的列表,但是重新排列,使每3后面紧跟着一个4。3不能移动索引位置,但每隔一个数字可以移动一次 示例的输出应为:
[1, 3, 4, 1, 1, 3, 4]
到目前为止,我的代码只能完成规则1和2。如何修改我的代码以适应这种情况
newList=[]
n=0
numCount= int(input())
while True:
try:
n = int(input())
except:
break
if len(newList) !=(numCount):
if n == 3:
newList.append(3)
newList.append(4)
else:
newList.append(n)
print(newList)
下面是一个函数,它正是这样做的:
def arrange_list(my_list):
# Copy the whole list
arranged_list=myList.copy()
# Find the all 4s
index_of_4s=[i for i, x in enumerate(arranged_list) if x == 4]
next_4=0
# Loop over the whole list
for i in range(len(arrangedList)):
if(arrangedList[i]==3): # We only care about 3s
# We swap the previously found 4 with a 1
arranged_list[index_of_4s[next_4]]=arranged_list[i+1]
arranged_list[i+1]=4
# We target the next 4
next_4=next_4+1
return arranged_list
如果我们用您的示例进行测试,我们会得到:
myList=[1, 3, 1, 4, 4, 3, 1]
arrange_list(myList)
#> [1, 3, 4, 1, 1, 3, 4]
我建议您首先获取输入列表中3和4的所有索引,然后将3后面的每个元素替换为4。它给出了以下代码,非常简短且易于阅读:
a = [1, 3, 1, 4, 4, 3, 1]
# Get the indexes of 3 and 4 in the list
indexesOf3 = [i for i,elem in enumerate(a) if elem == 3]
indexesOf4 = [i for i,elem in enumerate(a) if elem == 4]
# Swap each element following a 3 with a 4
for i3,i4 in zip(indexesOf3,indexesOf4):
a[i3+1], a[i4] = a[i4], a[i3+1]
print(a)
# [1, 3, 4, 1, 1, 3, 4]
注意:这个代码示例修改了输入列表,但显然它可以很容易地更新为一个函数,返回一个新列表并保持输入列表的原样。您的问题并没有得到很好的定义,并且没有考虑丢失场景。这段代码的工作非常简单,其思想是创建一个新列表 -在输入中找到3的位置 -在新列表中放置3,然后是4 -放置其余的元素
input_list = [1, 3, 1, 4, 4, 3, 1]
# Check the number of 3 and 4
n3 = input_list.count(3)
n4 = input_list.count(4)
if n3 > n4:
for i in range(n3-n4):
input_list.append(4)
elif n4 > n3:
for i in range(n4-n3):
input_list.append(3)
# Now let's look at the order. The 3 should not move and must be followed by a 4.
# Easy way, create a new list.
output_list = [None for i in range(len(input_list))]
# Then I'm using numpy to go faster but the idea is just to extract the ids are which the 3 are placed.
import numpy as np
# Place the 3 and the 4
for elt_3 in np.where(np.asarray(input_list) == 3)[0]:
output_list[elt_3] = 3
output_list[elt_3+1] = 4 # Must be sure that the input_list does not end by a 3 !!!
# Then we don't care of the position for the other numbers.
other_numbers = [x for x in input_list if x != 3 and x != 4]
for i, elt in enumerate(output_list):
if elt is None:
output_list[i] = other_numbers[0]
del other_numbers[0]
print (output_list)
在更紧凑的单循环版本中,它提供:
input_list = [1, 3, 1, 4, 4, 3, 1]
position_3 = np.where(np.asarray(input_list) == 3)[0]
other_numbers = [x for x in input_list if x != 3 and x != 4] # Not 3 and not 4
output_list = [None for i in range(len(input_list))]
for i, elt in enumerate(output_list):
if elt == 4:
continue
elif i not in position_3:
output_list[i] = other_numbers[0]
del other_numbers[0]
else:
output_list[i] = 3
output_list[i+1] = 4
我不确定我是否理解规则1。此外,规则2和4是相同的,与规则5不兼容。请重新制定.Yep规则不兼容,如果用户的输入不兼容怎么办?是否要添加额外的数字以使其兼容?输入和输出示例可能是了解必须执行的操作的最佳选择。@Mathieu我认为“每个3后面都有一个数字,不是3或4”表示输入列表,而不是输出。@RyanGrady问自己:如果在输入列表中遇到4,会发生什么?基本上,你只需要交换4s和1s。如果你得到所有4的位置,并且知道每3个之后只能有一个1,你就搜索一个3,然后用一个4替换下面的1。这很有效。但是,您如何解释将4与任何给定的数字(当然不是3)进行交换?工作非常完美通过在列表上循环一次也可以获得3和4的索引。我建议使用
循环,也可以使用类似a[-1]的检查=3
如果您在执行a[i3+1]
@Ev.Kounis时没有出现错误,那就太好了。谢谢,我完全同意您的看法。事实上,在这个例子中我没有寻找优化,目的只是解释所使用的算法,所以我保持原样。@Ev.Kounis我也同意,它可以增强。但是,如果输入列表的最后一个元素是3,则无法完成任务。我更愿意让代码尽可能简单。