我需要按0.05的间隔对从0到1的每个值组成的列表进行排列。
我已经尝试使用itertools的置换方法(或函数),但是该程序花了很多时间才能完成置换,甚至在运行Spyder时使它崩溃。我还需要在排列的每个实例中的每个数字加起来为1(在下面的代码片段中此示例)。我什至无法测试对代码所做的更改,因为这会使我的计算机停止工作。有什么建议吗?
weight.append(i for i in list(itertools.permutations(weights)) if sum(i)<=1.04 and sum(i)>=0.96)
我进行了两次总和检查,因为数字的总和未精确得出1,所以我不能只尝试if sum(i)==1
。确实没有将任何内容添加到列表中,我需要将结果添加到列表中,但这是一个不同的问题。
答案 0 :(得分:0)
您的评论揭示了您的追求。这不是排列,而是笛卡尔积。
在 Python 中,将其“翻译”为[Python 3.Docs]: itertools.product(*iterables, repeat=1)。
code.py :
#!/usr/bin/env python3
import sys
from itertools import product
def filter_values(values, min_sum=0, max_sum=100, count=3):
for item in product(values, repeat=count):
if min_sum <= sum(item) <= max_sum:
yield item
def main():
weights = [float(i) / 100 for i in range(0, 105, 5)]
print("Weights: {:}\n".format(weights))
filtered_weights = list(filter_values(weights, min_sum=0.96, max_sum=1.04)) # @TODO - cfati: !!! NOTA BENE: list(...) is for display purposes only! I guess its (disastrous) effects are quite familiar when it comes to large amounts of data !!!
print("Filtering yielded {:d} elements".format(len(filtered_weights)))
if (len(filtered_weights)):
print(" First: {:}\n Last: {:}".format(filtered_weights[0], filtered_weights[-1]))
if __name__ == "__main__":
print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
main()
print("\nDone.")
输出:
[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q056551640]> "e:\Work\Dev\VEnvs\py_064_03.07.03_test0\Scripts\python.exe" code.py Python 3.7.3 (v3.7.3:ef4ec6ed12, Mar 25 2019, 22:22:05) [MSC v.1916 64 bit (AMD64)] on win32 Weights: [0.0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0] Filtering yielded 231 elements First: (0.0, 0.0, 1.0) Last: (1.0, 0.0, 0.0) Done.
答案 1 :(得分:0)
考虑到问题的精确度(在注释中),您可以使用简单的列表理解来获得所有这些“排列”:
combos = [ (x/20,y/20,(20-x-y)/20) for x in range(21) for y in range(21-x) ]
# 231 combinations:
#
# [(0.0, 0.0, 1.0), (0.0, 0.05, 0.95), (0.0, 0.1, 0.9), (0.0, 0.15, 0.85), ...
# ... (0.95, 0.0, 0.05), (0.95, 0.05, 0.0), (1.0, 0.0, 0.0)]