我目前正在尝试迭代一个小的整数列表,并更新任何不满足绝对差条件的值,目的是在多个小列表上使用这个方法,作为一个更大的for循环的一部分。
我有以下清单:
y_list = [16, 29, 10]
此列表需要满足两个条件:
1.没有两个数字是相同的以及
1.每个数字应至少相差10
如果这些条件中的任何一个都不满足,则应调整数量,使其至少相差10。例如:
将y_list[0]
与y_list[1]
进行比较:它满足这两个条件并继续前进。
将y_list[0]
与y_list[2]
进行比较:它不满足条件2,并加上10减去现有差值。
将y_list[1]
与y_list[0]
进行比较:现在这两个条件都不满足了,但它没有调整y_list[0]
,而是将y_list[1]
增加10减去差值。
到目前为止,我已经编写了下面的代码,其中没有考虑到上面示例的最后一个元素,print语句不是必需的,但我只是使用它们来帮助我确保循环的不同部分是否被触发:
for i in range(len(y_list)):
print(f'Iteration {i}')
print(f'Old y_list: {y_list}')
for idx, value in enumerate(y_list):
difference = abs(value - y_list[i])
if value != y_list[i]:
print(f'Comparing {y_list[idx]} with {y_list[i]}')
print(f'Difference of {difference}')
if difference < 10:
print(f'Updating {y_list[idx]}\n')
y_list[idx] += 10 - difference
else:
continue
print()
print(f'New list{y_list}\n')
这给了我一个更新的列表,但显然它只在整个列表上迭代三轮。
Output:
Iteration 0
Old y_list: [16, 29, 10]
Comparing 29 with 16
Difference of 13
Comparing 10 with 16
Difference of 6
Updating 10
New list[16, 29, 14]
Iteration 1
Old y_list: [16, 29, 14]
Comparing 16 with 29
Difference of 13
Comparing 14 with 29
Difference of 15
New list[16, 29, 14]
Iteration 2
Old y_list: [16, 29, 14]
Comparing 16 with 14
Difference of 2
Updating 16
Comparing 29 with 14
Difference of 15
New list[24, 29, 14]
我尝试在第二个for循环之前使用while True
循环来继续迭代,但没有成功。
我见过all()
函数和itertools.takewhile()
满足条件的例子,但还没有能够让其中任何一个函数与while循环一起工作。
任何帮助都非常感谢!
5条答案
按热度按时间ki0zmccv1#
解决方案的要求并不完全清楚,因此我做了一些额外的假设:
1.列表中最低的数字不作调整
1.不得向下调整数字
1.对于相等的数字,调整哪个数字无关紧要(如果需要多次调整,则按哪个顺序调整数字)
1.除3外,应保留编号顺序
1.考虑到以上所有因素,调整应该是最小的。注意,忽略规则1和规则2可能会实现较低的调整,但这将使算法复杂得多。
鉴于上述情况,最好的方法是对排序的数据进行处理,即首先比较最小值与第二小值,然后比较第二小值与第三小值,依此类推。
pairwise
fromitertools
(从Python 3.10开始提供)非常适合进行这种迭代,对于旧版本的python,你可以使用zip来创建类似的东西。使用pairwise
,检查可以归结为一个简单的:对于较早的python版本,在排序项上使用
zip
:为了调整列表,你也可以使用pairwise,但是当你正在动态地改变列表时,你需要使用索引来做任何改变,
enumerate
提供了这些:mwngjboj2#
另一个镜头:
你可以对输入数组进行排序(记住原始索引),确保值之间的差异至少为10,然后将值按原始顺序放回:
图纸:
qeeaahzv3#
如果你不在乎维持秩序,我会这么做:
给你:
如果你真的关心排序,那么@andrej-kesely的答案在我看来是个赢家。
xzv2uavs4#
itertools中的
accumulate
函数可以使这一过程变得非常简单,因为它将遍历列表,处理最后一个值和当前值:如果不允许使用库,可以使用extend方法获得类似的结果:
如果需要在同一个列表示例中“就地”更改值,
enumerate()
可以帮助遍历和索引:[EDIT]下面是一个流程示例,该流程锚定最小的元素,以保持该元素最小的方式前后工作(即最小限度地调整其周围的其他元素):
dbf7pr2w5#
创建一个函数来计算列表是否满足条件,然后使用一个while循环来运行,直到该函数返回True为止。技巧是使用更紧凑的代码来检查唯一性并进行所有比较。对于唯一性,我们可以只比较集合和列表,如果长度匹配,则所有元素都是唯一的。对于比较,我们使用
itertools.combinations
来生成所有索引对。如果遇到任何失败条件,我们立即返回False。如果它通过了检查,我们最终返回True。