2013-09-24 1 views
2

Я делаю модуль python, который требует много заданных манипуляций. Я пробовал много вещей, но я не преуспел. Во-первых, я имею дело с множествами в трех измерениях, а затем я использую itertools функцию продукта, чтобы сделать декартово произведение:Манипулирование многомерным множеством: маргинализация, расширение, членство

from itertools import product 

# Marginal sets 
x1 = set(['u1', 'd1']) 
x2 = set(['u2', 'd2']) 
x3 = set(['u3', 'd3']) 

# Cartesian product of x1,x2,x3 
X = set(product(x1,x2,x3)) 

>>> X 
set([('d1', 'u2', 'u3'), ('u1', 'u2', 'u3'), ('u1', 'u2', 'd3'), ('d1', 'd2', 'u3'), ('u1', 'd2', 'd3'), ('d1', 'd2', 'd3'), ('u1', 'd2', 'u3'), ('d1', 'u2', 'd3')]) 

Я хотел бы расширить пересечение множеств таким образом, что она принимает следующее:

>>>set('d1') & X # Return elements of X containing 'd1' 
set([('d1', 'u2', 'u3'), ('d1', 'd2', 'u3'), ('d1', 'd2', 'd3'), ('d1', 'u2', 'd3')]) 

А также следующее:

>>>set('d1','u2') & X # Return elements of X containing 'd1' 
set([('d1', 'u2', 'u3'), ('d1', 'u2', 'd3')]) 

Я также хотел бы расширить снова декартово произведение, добавив новое измерение, например,

x4 = set(['u4', 'd4']) 
Y = cartesianproduct(X,x4) 
>>>Y 
set([('u1', 'u2', 'u3', 'd4'), ('d1', 'd2', 'u3', 'd4'), ('u1', 'u2', 'u3', 'u4'), ('u1', 'u2', 'd3', 'u4'), ('d1', 'u2', 'u3', 'u4'), ('d1', 'd2', 'd3', 'u4'), ('d1', 'd2', 'u3', 'u4'), ('d1', 'd2', 'd3', 'd4'), ('u1', 'u2', 'd3', 'd4'), ('u1', 'd2', 'd3', 'd4'), ('d1', 'u2', 'd3', 'd4'), ('d1', 'u2', 'd3', 'u4'), ('u1', 'd2', 'u3', 'u4'), ('d1', 'u2', 'u3', 'd4'), ('u1', 'd2', 'd3', 'u4'), ('u1', 'd2', 'u3', 'd4')]) 

Наконец, я хотел бы, чтобы удалить измерение:

Z = remove(x3,X) 
>>>Z 
set([('d1', 'd2'), ('u1', 'u2'), ('u1', 'd2'), ('d1', 'u2')]) 

Я новичок в Python, и я чувствую, что я делаю это совершенно неправильно, смешивая списки, кортежи и наборы в неправильные способы, может быть ...

Пожалуйста нежный :)

ответ

2

Я хотел бы работать со списком наборов вместо:

X = map(set,product(x1,x2,x3)) 

def has_element(X,Y): 
    return [y for y in Y if len(y.intersection(X))] 

print has_element(['d1','u1'],X) 

>>> [set(['d2', 'u1', 'd3']), set(['d2', 'u1', 'u3']), set(['u1', 'd3', 'u2']), set(['u1', 'u3', 'u2']), set(['d2', 'd3', 'd1']), set(['d2', 'u3', 'd1']), set(['u2', 'd3', 'd1']), set(['u2', 'u3', 'd1'])] 

Для вашей второй функции:

def new_product(X,Y): 
    Z = [] 
    for a,b in product(X,Y): 
     ab = b.copy() 
     ab.add(a) 
     Z.append(ab) 
    return Z 

print new_product(set(['d4','u4']),X) 

>>> [set(['u1', 'd2', 'd3', 'u4']), set(['u1', 'd2', 'u3', 'u4']), set(['u4', 'u1', 'd3', 'u2']), set(['u4', 'u1', 'u3', 'u2']), set(['u4', 'd2', 'd3', 'd1']), set(['u4', 'd2', 'u3', 'd1']), set(['u4', 'd1', 'd3', 'u2']), set(['u4', 'd1', 'u3', 'u2']), set(['u1', 'd4', 'd2', 'd3']), set(['u1', 'd4', 'd2', 'u3']), set(['d4', 'u1', 'd3', 'u2']), set(['d4', 'u1', 'u3', 'u2']), set(['d4', 'd2', 'd3', 'd1']), set(['d4', 'd2', 'u3', 'd1']), set(['d4', 'd1', 'd3', 'u2']), set(['d4', 'd1', 'u3', 'u2'])] 

Последняя функция:

def remove(X,Y): 
    Z = Y[:] # Make a copy 
    for z in Z: 
     for x in X: 
      if x in z: 
       z.remove(x) 
    return Z 

print remove(x3,X) 

>>> [set(['d2', 'd1']), set(['d2', 'd1']), set(['u2', 'd1']), set(['u2', 'd1'])] 
+0

Я редактировал оригинальный вопрос, я забыл упомянуть, что мне также нужно has_element (('d1', 'u2'), X) работать аналогичным образом ... –

+1

@FelipeAguirre Обновлен ответ на работу с вашим требованием. Просто обратите внимание, что теперь вы не можете передать один аргумент, его нужно обернуть в итерируемый объект. Используйте обратные элементы для написания встроенного кода в комментариях \ 'this \' становится 'this'. – Hooked

+0

Я не был достаточно ясен, ожидаемый вывод 'has_element (('d1', 'u2'), X)' должен возвращать элементы, которые имеют '' d1'' AND ''u2''. Ваше решение возвращает элементы, которые имеют '' d1'' OR ''u2'' –