自定义产品需要实际实现itertools.product。

huangapple go评论100阅读模式
英文:

Custom product needs real implementation of itertools.product

问题

I am trying to implement custom itertools.product because I don't to create the whole cartesian product but I want last couple of elements to be fixed. I just copied the code from here https://docs.python.org/3/library/itertools.html#itertools.product

  1. def product(*args, repeat=1):
  2. # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
  3. # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
  4. pools = [tuple(pool) for pool in args] * repeat
  5. result = [[]]
  6. for pool in pools:
  7. result = [x+[y] for x in result for y in pool]
  8. for prod in result:
  9. yield tuple(prod)

and tried to customize. However, even without any change it has different behaviour than

  1. for el in itertools.product(range(2), 30)
  2. print(el)

Cases 1: the code snippet (function product) I provide from docs. First (as you can see the code) create the whole result and then yield one by one. But

Case 2.

  1. for el in itertools.product(range(2), 30)
  2. print(el)

Yields the elements immediately which is something I would expect from generator because sometimes the product doesn't fit into my memory.

Does anybody know the real implementation of itertools.product?

英文:

I am trying to implement custom itertools.product because I don't to create the whole cartesian product but I want last couple of elements to be fixed. I just copied the code from here https://docs.python.org/3/library/itertools.html#itertools.product

  1. def product(*args, repeat=1):
  2. # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
  3. # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
  4. pools = [tuple(pool) for pool in args] * repeat
  5. result = [[]]
  6. for pool in pools:
  7. result = [x+[y] for x in result for y in pool]
  8. for prod in result:
  9. yield tuple(prod)

and tried to customize. However, even without any change it has different behaviour than

  1. for el in itertools.product(range(2), 30)
  2. print(el)

Cases 1: the code snippet (function product) I provide from docs. First (as you can see the code) create the whole result and then yield one by one. But

Case 2.

  1. for el in itertools.product(range(2), 30)
  2. print(el)

Yields the elements immediately which is something I would expect from generator because sometimes the product doesn't fit into my memory.

Does anybody know the real implementation of itertools.product?

答案1

得分: 1

以下是代码部分的中文翻译:

  1. 这相当接近[实际实现][1]
  2. def product(*args, repeat=1):
  3. pools = [tuple(pool) for pool in args] * repeat
  4. npools = len(pools)
  5. try:
  6. result = [pool[0] for pool in pools]
  7. except IndexError:
  8. return
  9. yield result
  10. indices = [0] * npools
  11. p = npools - 1
  12. while p >= 0:
  13. pool = pools

  14. indices

    += 1

  15. try:

  16. result

    = pool[indices

    ]

  17. except IndexError:

  18. indices

    = 0

  19. result

    = pool[indices

    ]

  20. p -= 1

  21. continue

  22. else:

  23. p = npools - 1

  24. yield tuple(result)

  25. 这是应用于您原始问题时的效果

  26. >>> big = product(range(2), repeat=30)

  27. >>> next(big)

  28. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

  29. >>> next(big)

  30. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)

  31. >>> next(big)

  32. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0)

  33. >>> next(big)

  34. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)

  35. [1]: https://github.com/python/cpython/blob/42f54d1f9244784fec99e0610aa05a5051e594bb/Modules/itertoolsmodule.c#L2192

英文:

This is pretty close to the actual implementation:

  1. def product(*args, repeat=1):
  2. pools = [tuple(pool) for pool in args] * repeat
  3. npools = len(pools)
  4. try:
  5. result = [pool[0] for pool in pools]
  6. except IndexError:
  7. return
  8. yield result
  9. indices = [0] * npools
  10. p = npools - 1
  11. while p >= 0:
  12. pool = pools

  13. indices

    += 1

  14. try:

  15. result

    = pool[indices

    ]

  16. except IndexError:

  17. indices

    = 0

  18. result

    = pool[indices

    ]

  19. p -= 1

  20. continue

  21. else:

  22. p = npools - 1

  23. yield tuple(result)

This is how it looks when applied to your original problem:

  1. >>> big = product(range(2), repeat=30)
  2. >>> next(big)
  3. [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
  4. >>> next(big)
  5. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1)
  6. >>> next(big)
  7. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0)
  8. >>> next(big)
  9. (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1)

huangapple
  • 本文由 发表于 2023年5月6日 19:28:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76188611.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定