Создание переменной, которая объединяет несколько перечислений в огромном списке - PullRequest
1 голос
/ 20 декабря 2011

Я бы хотел найти самый простой способ создать огромный список.

Допустим, у меня есть три шестигранных кубика, поэтому у каждого из них будет значение randint(1,6).Я хочу, чтобы набор значений охватывал все возможные способы объединения этих трех чисел, чтобы это мог быть die1 * die2 + die3 или это die1 ** die3 - die2 и т. Д.

Я бы хотелопределите некоторую переменную Z, которая равна сложению, вычитанию, умножению и т. д. Таким образом, я мог бы сказать die1 Z die2 Z die3, и это привело бы меня к огромному списку, без необходимости печатать его.Возможно ли это в Python?Любые идеи будут с благодарностью.

Ответы [ 2 ]

2 голосов
/ 20 декабря 2011

Здесь важно знать, что вы можете передать функцию в качестве аргумента другой функции (или в списке).Как только вы поймете, что эту проблему становится гораздо проще решить.

Если вам нужно понимание списка:

from operator import add,sub,mul,div
funcs = [add,sub,mul,div]
die = [1,2,3,4,5,6]

results = [f(x,y) if y != 0 else None for x in die for y in [g(z,w) for z in die for w in die for g in funcs] for f in funcs]

Обратите внимание, что в нем содержится «Нет», где обычно делится на ноль.

Это намного понятнее, если вы разделите его на функцию.Он принимает два списка чисел и список операций и возвращает все результаты:

def results(funcs, xs, ys):
  out = []
  for f in funcs:
    for x in xs:
      for y in ys:
        try:
          out.append(f(x,y))
        except ZeroDivisionError:
          pass
  return out

Это не имеет ничего, где произошло бы деление на ноль.Используйте как results(funcs,die,results(funcs,die,die)), чтобы получить все результаты.

Оба из них имеют много дубликатов в своих результатах, поэтому в зависимости от того, что вы на самом деле хотите сделать, вы можете хотеть set вместо list.

Кроме того, просто подумайте об этом, но в зависимости от того, что вы планируете делать, вы можете получить results вместо генератора:

def results(funcs, xs, ys):
  for f in funcs:
    for x in xs:
      for y in ys:
        try:
          yield f(x,y)
        except ZeroDivisionError:
          pass

Если вы работаетедля действительно больших наборов результатов, но вы хотите просматривать их один за другим, это лучший вариант, чем создание всего списка.

0 голосов
/ 20 декабря 2011

Я думаю, вы пытаетесь спросить, как лучше всего перегрузить оператор для декартового произведения в python.

Попробуйте использовать product из itertools:

from itertools import *
die_outcomes = [1,2,3,4,5,6]
list(product(product(die_outcomes, die_outcomes), die_outcomes))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...