Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
编码时n个未知列表的Python笛卡尔积 问题: 在事先不知道有多少个列表的情况下,生成某些列表的笛卡尔乘积的最佳方法是什么?_Python - Fatal编程技术网

编码时n个未知列表的Python笛卡尔积 问题: 在事先不知道有多少个列表的情况下,生成某些列表的笛卡尔乘积的最佳方法是什么?

编码时n个未知列表的Python笛卡尔积 问题: 在事先不知道有多少个列表的情况下,生成某些列表的笛卡尔乘积的最佳方法是什么?,python,Python,如果你愿意,你可以在这里停止阅读 背景 我没有钱上学,所以我正在努力自学编程 在公路收费站上夜班时使用互联网。我有 决定尝试解决一些“编程挑战”问题作为练习 编程作业 以下是我试图解决的问题,TopCoder的属性: http://community.topcoder.com/stat?c=problem_statement&pm=3496 我不会复制和粘贴完整的描述,以尊重他们的版权声明 但我假设我可以总结它,只要我不逐字逐句地使用它 (尽管如此) 总结 如果历史股票价格的“加权和

如果你愿意,你可以在这里停止阅读


背景 我没有钱上学,所以我正在努力自学编程 在公路收费站上夜班时使用互联网。我有 决定尝试解决一些“编程挑战”问题作为练习

编程作业 以下是我试图解决的问题,TopCoder的属性:

http://community.topcoder.com/stat?c=problem_statement&pm=3496
我不会复制和粘贴完整的描述,以尊重他们的版权声明 但我假设我可以总结它,只要我不逐字逐句地使用它 (尽管如此)

总结 如果历史股票价格的“加权和”是获得的附录之和 将这些价格的子集乘以相等数量的“权重” 因子,前提是后者加起来为1.0,并从给定集合中选择 对于有效值[-1.0,-0.9,…,0.9,1.0],请在所有 作为函数参数提供的历史数据,检查5价格 一次,预测下一个价格并返回“权重”的排列 产生最低平均预测误差的“因子”。至少会有 每次运行中有6个股票价格,因此至少有一个预测是有保证的,即最终预测 结果应在1E-9范围内准确

测试数据 格式:

  • 一行用于输入数据,采用
    列表
    格式
  • 一行用于预期结果
  • 一个空行作为间隔符
下载地址:

我的解决方案
导入itertools
#对于要在加权和中使用的因子排列,应选择它
#所有因素之和等于1。
加权总和=1.0
因子可用于加权总和=λx:总和(x)=加权总和
#历史股价数据应使用宽度的滑动窗口进行检查
#5预测下一个价格时。
N_近期价格=5
#加权因子的有效值为:[-1.0,-0.9,…,0.9,1.0]
有效的_权重=[x/10。对于范围内的x(-10,11)]
一个预先计算的有效权重列表要考虑。这是笛卡尔式的
#仅考虑以下组合的有效重量集的乘积:
#作为加权和的组成部分有效。
笛卡尔乘积系数=[有效权重]*N最近的价格
权重的所有置换=itertools.product(*笛卡尔乘积因子)
加权和加权=过滤器(因子可以在加权和中使用),
所有_置换_权重_)
#生成器函数,用于从数据集中获取给定宽度的滑动窗口
def滑动窗口(数据、窗口宽度):
对于范围内的i(长度(数据)-窗口宽度):
产量数据[i:i+窗宽],数据[i+窗宽]
def平均值错误(数据):
#提供的数据将保证至少一次迭代
n_迭代次数=len(数据)-5
最佳平均误差=无
考虑每个有效的权重(例如权重的置换)
对于加权和权重中的权重:
#跟踪此权重的预测误差
此权重的错误数=[]
对于历史数据,下一步在滑动窗口中预测(数据,
N_近期价格):
预测=总和([a*b代表a,b在zip中(加权,历史数据)])
此加权.append的错误(abs(下一个预测-预测))
平均误差=总和(此加权的误差)/n次迭代
如果average_error==0:返回average_error
最佳平均错误=(如果不是最佳平均错误,则为平均错误)
最小值(平均误差、最佳平均误差)
返回最佳平均错误
def main():
打开('data.txt')作为输入文件:
尽管如此:
data=eval(input_file.readline())
预期结果=eval(输入文件.readline())
间隔符=输入_文件.readline()
如果不是垫片:
打破
结果=平均误差(数据)
打印预期结果,结果,(预期结果-结果)<1e-9
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

我的问题 我不是要求对我的解决方案进行代码审查,因为这将是一个错误的StackExchange论坛。在这种情况下,我会将我的解决方案发布到“代码审查”中

我的问题是小的,精确的,明确的,符合这个网站的格式(希望如此)

在我的代码中,我使用itertools生成列表的笛卡尔积。本质上,我自己并没有解决问题的关键,而是将解决方案委托给一个为我解决问题的库。如果我想从这些练习中学习,我认为这是错误的方法。我应该自己做最难的部分,否则为什么还要做这个练习呢?所以我想问你:


  • 在事先不知道有多少个列表的情况下,生成某些列表的笛卡尔乘积的最佳方法是什么?

这就是我想知道的,如果你愿意,你可以评论我的代码。这是值得欢迎的,即使它通过了所有的测试(总是有更好的方法做事情,特别是如果你是像我这样的初学者),但是为了让这个问题“恰到好处”,我只关注代码的一个方面,一个具体的问题,一些我不满意的东西。让我告诉你更多,我还将分享经典的“你已经尝试了什么”

显然,如果我知道列表的数量,我就可以键入一些嵌套for循环,就像本练习中的顶级解算器在竞赛中所做的那样。我试着编写一个函数,对未知数量的列表执行此操作,但我不确定采用哪种方法。第一种方法是编写递归函数。从列表1中,取元素1并将其与列表2的元素1组合,然后是列表3的元素1,
import itertools

# For a permutation of factors to be used in a weighted sum, it should be chosen
# such than the sum of all factors is 1.
WEIGHTED_SUM_TOTAL = 1.0
FACTORS_CAN_BE_USED_IN_WEIGHTED_SUM = lambda x: sum(x) == WEIGHTED_SUM_TOTAL

# Historical stock price data should be examined using a sliding window of width
# 5 when making predictions about the next price.
N_RECENT_PRICES = 5

# Valid values for weighting factors are: [-1.0, -0.9, ..., 0.9, 1.0]
VALID_WEIGHTS = [x / 10. for x in range(-10, 11)]

# A pre-calculated list of valid weightings to consider. This is the cartesiant
# product of the set of valid weigths considering only the combinations which
# are valid as components of a weighted sum.
CARTESIAN_PRODUCT_FACTORS = [VALID_WEIGHTS] * N_RECENT_PRICES
ALL_PERMUTATIONS_OF_WEIGHTS = itertools.product(*CARTESIAN_PRODUCT_FACTORS)
WEIGHTED_SUM_WEIGHTS = filter(FACTORS_CAN_BE_USED_IN_WEIGHTED_SUM,
                              ALL_PERMUTATIONS_OF_WEIGHTS)

# Generator function to get sliding windows of a given width from a data set
def sliding_windows(data, window_width):

  for i in range(len(data) - window_width):
    yield data[i:i + window_width], data[i + window_width]

def avg_error(data):

  # The supplied data will guarantee at least one iteration
  n_iterations = len(data) - 5

  best_average_error = None

  # Consider each valid weighting (e.g. permutation of weights)
  for weighting in WEIGHTED_SUM_WEIGHTS:

    # Keep track of the prediction errors for this weighting
    errors_for_this_weighting = []

    for historical_data, next_to_predict in sliding_windows(data,
                                                            N_RECENT_PRICES):

      prediction = sum([a * b for a, b in zip(weighting, historical_data)])
      errors_for_this_weighting.append(abs(next_to_predict - prediction))

    average_error = sum(errors_for_this_weighting) / n_iterations

    if average_error == 0: return average_error

    best_average_error = (average_error if not best_average_error else
      min(average_error, best_average_error))

  return best_average_error

def main():
  with open('data.txt') as input_file:
    while True:
        data = eval(input_file.readline())
        expected_result = eval(input_file.readline())
        spacer = input_file.readline()
        if not spacer:
          break
        result = avg_error(data)
        print expected_result, result, (expected_result - result) < 1e-9

if __name__ == '__main__':
    main()
00000
00001
00002
...
00009
00010
00011
00012
...
99998
99999
ax1
ax2
ay1
ay2
bx1
bx2
by1
by2
cy1
cy2
cx1
cx2
def lex_gen(bounds):
    elem = [0] * len(bounds)
    while True:
        yield elem
        i = 0
        while elem[i] == bounds[i] - 1:
            elem[i] = 0
            i += 1
            if i == len(bounds):
                raise StopIteration
        elem[i] += 1

def cart_product(lists):
    bounds = [len(lst) for lst in lists]
    for elem in lex_gen(bounds):
        yield [lists[i][elem[i]] for i in range(len(lists))]


for k in cart_product([['1', '2'], ['x', 'y'], ['a', 'b', 'c']]):
    print(k)
[ (x,y) for x in reals for y in reals ]
def cartesian_product(*X):
  return reduce(
    lambda accum, list: 
      [ tup + (item,) for tup in accum for item in list ],
    X,
    [()]
  )
[(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]
import itertools
combs=itertools.product(*lists)
>>> c=[['3', '5', '7'], ['100'], ['1', '2', '3']]
>>> z=itertools.product(*c)
>>> for ii in z:
...     print ii
... 
('3', '100', '1')
('3', '100', '2')
('3', '100', '3')
('5', '100', '1')
('5', '100', '2')
('5', '100', '3')
('7', '100', '1')
('7', '100', '2')
('7', '100', '3')