J'utilise python 2.7 et j'ai la liste suivante:
for name, val in my_dict.iteritems():
for v in val:
for i in list1:
if i in v:
print name
break
Et puis j'ai un dictionnaire comme celui-ci:
my_dict = {}
my_dict["GI2/1/1"] = [
'switchport port-security maximum 10',
'switchport port-security maximum 3 vlan access',
'switchport port-security maximum 1 vlan voice',
'switchport port-security aging time 25',
'switchport port-security aging type inactivity',
'switchport port-security'
]
my_dict["GI2/1/2"] = [
'switchport port-security maximum 5',
'switchport port-security maximum 5 vlan access',
'switchport port-security maximum 3 vlan voice',
'switchport port-security aging time 20',
'switchport port-security aging type inactivity',
'switchport port-security'
]
my_dict["GI2/1/3"] = [
'switchport port-security maximum 10',
'switchport port-security maximum 3 vlan access',
'switchport port-security maximum 1 vlan voice',
'switchport port-security'
]
J'essaie de trouver un moyen de rechercher les valeurs, mais il faudrait que cela corresponde aux deux entrées de la liste1
J'ai le code suivant, mais il correspondra à un et ensuite éclatera, je sais pourquoi son éclatement, mais je ne peux pas trouver un moyen de le forcer à correspondre aux deux entrées, puis à éclater. Je sais que je peux utiliser all () pour tout faire correspondre exactement, mais je cherche simplement à voir si ces deux entrées existent.
list1 = ['switchport port-security maximum', 'switchport port-security aging']
Le but est de ne produire que GI2 / 1 / 1 et GI2 / 1/2 car le GI2 / 1/3 ne correspond pas aux deux entrées
4 Réponses :
Je ne sais pas si j'ai compris ce que vous voulez mais quelque chose comme?
def cont(l,s):
for i in l:
if s in i:
return True
return False
for name, val in my_dict.iteritems():
happy=True
for i in list1:
if not cont(val,i):
happy=False
if happy:
print name
break
(et supprimez simplement le saut si vous voulez lister toutes les entrées correspondant à vos contraintes)
p >
Vous pouvez parcourir Ceci renvoie: list1 pour générer des ensembles de clés dans my_dict où l'une des sous-listes de chaînes contient le mot-clé donné dans list1 code >, puis utilisez la fonction réduire pour produire la sortie souhaitée via le jeu d'intersection: set(['GI2/1/1', 'GI2/1/2'])
reduce(set.intersection, ({n for n, l in my_dict.iteritems() if any(k in i for i in l)} for k in list1))
Vous pouvez créer un nouveau dict qui capture les résultats.
my_list = [[
'switchport port-security maximum 10',
'switchport port-security maximum 3 vlan access',
'switchport port-security maximum 1 vlan voice',
'switchport port-security aging time 25',
'switchport port-security aging type inactivity',
'switchport port-security'
], [
'switchport port-security maximum 5',
'switchport port-security maximum 5 vlan access',
'switchport port-security maximum 3 vlan voice',
'switchport port-security aging time 20',
'switchport port-security aging type inactivity',
'switchport port-security'
], [
'switchport port-security maximum 10',
'switchport port-security maximum 3 vlan access',
'switchport port-security maximum 1 vlan voice',
'switchport port-security'
]]
result = []
for sub_list in my_list:
if all([True if any([config in item for item in sub_list]) else False for config in list1]):
result.append(True)
else:
result.append(False)
#[True, True, False]
Cela peut certainement être fait en une seule ligne, mais j'ai pensé qu'il serait peut-être plus facile de voir ce qui se passe en deux étapes. Je stocke toutes les correspondances dans une liste qui est transformée en un ensemble (supprimer les doublons) qui est ensuite comparé aux correspondances souhaitées dans list1 .
MODIFIER : Comme @blhsing l'a souligné, set en python n'est pas ordonné. Au lieu de créer une liste à partir de mes valeurs dans result , je crée un set à partir de list1 depuis que je ne pensez pas qu'OP aura des doublons dans list1.
Une autre façon serait d'utiliser all et de vérifier tous les éléments.
result = {key: set([item for item in list1 for things in val if item in things]) for key, val in my_dict.iteritems()}
result = [key for key, val in result.iteritems() if all([config in val for config in list1])]
# ['GI2/1/1', 'GI2/1/2']
EDIT # 2: À cause de la demande d'OP dans les commentaires. Voici un autre moyen potentiel. (Motivé par la réponse de @ Josué Cortina ci-dessous).
result = {key: set([item for item in list1 for things in val if item in things]) for key, val in my_dict.iteritems()}
#{'GI2/1/1': {'switchport port-security maximum', 'switchport port-security aging'}, 'GI2/1/2': {'switchport port-security maximum', 'switchport port-security aging'}, 'GI2/1/3': {'switchport port-security maximum'}}
result = [key for key, val in result.iteritems() if val == set(list1)]
#['GI2/1/1', 'GI2/1/2']
Si nous n'avons qu'une liste de listes et que nous voulons que les booléens voient si la sous-liste correspond à ce que nous recherchons, alors ci-dessus pourrait être une solution possible.
Wow parfait, exactement ce que je cherchais, serait-il possible d'accomplir la même chose si elles étaient toutes les deux des listes et l'une d'elles n'était pas un dictionnaire. Donc, si je n'avais pas besoin d'obtenir le nom dont j'avais juste besoin pour passer aux listes et voir si elles correspondent ou non, comment changerais-je le code pour quelque chose comme ça?
Voulez-vous dire si list1 et my_dict étaient en fait des list ? Donc, my_dict ou plus exactement my_list est une liste de listes?
Corriger s'ils étaient les deux listes sans les noms d'interface, donc je veux juste voir si la liste des configurations d'interface correspond à la liste que je recherche?
Donc, si la liste ressemblait à ceci my_list_1 = ['switchport port-security maximum 5', 'switchport port-security maximum 5 vlan access', 'switchport port-security maximum 3 vlan voice', 'switchport port-security vieillissement time 20' , 'switchport port-security ageing type inactivity', 'switchport port-security'] et s'il trouve les deux correspondances avec une autre liste, alors affichez "matched" ou quelque chose comme ça juste pour confirmer qu'il a trouvé les deux correspondances
Si je vous comprends bien, vous demandez une comparaison de liste. set ([item for item in list1 for things in my_list_1 if item in things]) == list1 renverra True si les deux éléments de list sont dans ma_liste_1 . C'est ce que vous demandiez?
Cette réponse est en fait incorrecte car les ensembles ne sont pas ordonnés en Python et list (val) ne sera donc pas nécessairement égal à list1 .
@blhsing Vous avez raison. J'ai complètement oublié ça. Je mettrai à jour ma réponse pour cela.
Oui correct, c'est ce que je recherche, mais sans utiliser de dictionnaire en utilisant simplement 2 listes.
Vous pouvez simplement utiliser str.startswith (si vous ne vous souciez pas de la position, vous pouvez vous en tenir à dans ) et le combiner avec all et any:
GI2/1/1 GI2/1/2
Vous pouvez utiliser des expressions régulières , même si cela peut être excessif :
import re
regexps = [re.compile(i) for i in list1]
for name, val in my_dict.iteritems():
if all(any(regexp.match(v) for v in val) for regexp in regexps):
print name
for name, val in my_dict.iteritems():
if all(any(v.startswith(l) for v in val) for l in list1):
print name
Je pense à ces deux méthodes sont assez compréhensibles: vous savez ce qu'ils font juste en les regardant
J'espère que cela vous aidera!
Quel est le résultat attendu? Je ne sais pas ce que vous entendez par "rechercher les valeurs, mais il faudrait qu'il corresponde aux deux entrées de list1".
Je voudrais qu'il ne produise que GI2 / 1/1 et GI2 / 1/2 car le GI2 / 1/3 ne correspond pas sur les deux
Le simple fait de supprimer le
breakpourrait fonctionner?breakne fait que sortir de la bouclelist1, il devrait continuer avec les boucles externes.Josue a raison, il suffit de supprimer la pause.