Melhor maneira de encontrar a interseção de vários conjuntos?
-
23-09-2019 - |
Pergunta
Eu tenho uma lista de conjuntos:
setlist = [s1,s2,s3...]
Eu quero s1 ∩ s2 ∩ s3...
Posso escrever uma função para fazer isso executando uma série de pares s1.intersection(s2)
, etc.
Existe uma maneira recomendada, melhor ou integrada?
Solução
A partir da versão 2.6 do Python você pode usar vários argumentos para set.intersection()
, como
u = set.intersection(s1, s2, s3)
Se os conjuntos estiverem em uma lista, isso se traduz em:
u = set.intersection(*setlist)
onde *a_list
é expansão da lista
Outras dicas
A partir de 2.6, set.intersection
leva arbitrariamente muitos iteráveis.
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s3 = set([2, 4, 6])
>>> s1 & s2 & s3
set([2])
>>> s1.intersection(s2, s3)
set([2])
>>> sets = [s1, s2, s3]
>>> set.intersection(*sets)
set([2])
Não é possível.As únicas maneiras de fazer isso são:
- .
- ClientContext (string) - inicializa uma nova instância do Classe clientContext para o site do SharePoint com o especificado URL absoluto.
- ClientContext (URI) - inicializa uma nova instância do ClientContext
classe para o site com o objeto URI especificado.
mas você pode usar site.Openwebbyid () e obter web por GUID
Se você não tem Python 2.6 ou superior, a alternativa é escrever um explícito para o loop:
def set_list_intersection(set_list):
if not set_list:
return set()
result = set_list[0]
for s in set_list[1:]:
result &= s
return result
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])
Você também pode usar reduce
:
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])
No entanto, muitos programadores python não gostam, incluindo o próprio Guido:
Cerca de 12 anos atrás, o Python Aquired Lambda, Reduce (), Filter () e Map (), cortesia de (acredito) um hacker que sentiu falta deles e enviou patches de trabalho. Mas, apesar do valor do RP, acho que esses recursos devem ser cortados do Python 3000.
Então agora reduza (). Na verdade, esse é o que eu sempre odiei, porque, além de alguns exemplos envolvendo + ou *, quase toda vez que vejo uma chamada reduzida () com um argumento de função não trivial, preciso pegar caneta e papel para Diagrama o que realmente está sendo alimentado com essa função antes de entender o que o reduz () deve fazer. Portanto, na minha opinião, a aplicabilidade de reduz () é praticamente limitada aos operadores associativos e, em todos os outros casos, é melhor escrever o loop de acumulação explicitamente.
Aqui estou oferecendo uma função genérica para vários interseções, tentando tirar proveito do melhor método disponível:
def multiple_set_intersection(*sets):
"""Return multiple set intersection."""
try:
return set.intersection(*sets)
except TypeError: # this is Python < 2.6 or no arguments
pass
try: a_set= sets[0]
except IndexError: # no arguments
return set() # return empty set
return reduce(a_set.intersection, sets[1:])
Guido pode não gostar reduce
, mas eu gosto disso :)