Je dois vérifier si list1 est une sous-liste de list2 (vrai; si chaque entier de list2 commun à list1 est dans le même ordre d'index que dans list1)
def sublist(lst1,lst2):
for i in range(len(lst1)):
if lst1[i] not in lst2:
return False
for j in range(len(lst2)):
if (lst1[j] in lst2) and (lst2.index(lst1[i+1]) > lst2.index(lst1[i])):
return True
Quelqu'un peut-il m'aider ... pourquoi ça ne marche pas?
je dois vérifier si list1 est une sous-liste de list2 (vrai; si chaque entier de list2 commun à list1 est dans le même ordre d'index que dans list1)
Votre code ne fonctionne pas car dès qu'un élément de liste dans ls1 ne se produit pas dans ls2, il renvoie immédiatement False.
Cela crée deux listes qui ne contiennent que les éléments communs (mais dans leur ordre d'origine), puis renvoie True lorsqu'elles sont identiques:
def sublist(lst1, lst2):
ls1 = [element for element in lst1 if element in lst2]
ls2 = [element for element in lst2 if element in lst1]
return ls1 == ls2
edit: Une variante économe en mémoire:
def sublist(ls1, ls2):
'''
>>> sublist([], [1,2,3])
True
>>> sublist([1,2,3,4], [2,5,3])
True
>>> sublist([1,2,3,4], [0,3,2])
False
>>> sublist([1,2,3,4], [1,2,5,6,7,8,5,76,4,3])
False
'''
def get_all_in(one, another):
for element in one:
if element in another:
yield element
for x1, x2 in Zip(get_all_in(ls1, ls2), get_all_in(ls2, ls1)):
if x1 != x2:
return False
return True
Solution efficace en mémoire basée sur la réponse de M. Morgan. Prend en compte que pour être une sous-liste, la sous-liste doit être trouvée dans le même ordre dans la super-liste.
La variable k
garde la trace de la longueur des caractères correspondants. Lorsque cela correspond à la longueur de notre sous-liste, nous pouvons renvoyer true.
La variable s
garde la trace de la valeur de départ. Je garde cette trace de sorte qu'un scénario de test tel que sublist(["1", "1", "2"],["0", "1", "1", "1", "2", "1", "2"])
avec répétitions superflues de la première entrée n'affecte pas la réinitialisation actuelle de l'index lorsqu'elle n'est pas appariée. Une fois que la valeur de départ change, la variable s
devient inutile, de sorte que ce cas ne se déclenche pas au milieu d'un motif.
def sublist(sublist, lst):
if not isinstance(sublist, list):
raise ValueError("sublist must be a list")
if not isinstance(lst, list):
raise ValueError("lst must be a list")
sublist_len = len(sublist)
k=0
s=None
if (sublist_len > len(lst)):
return False
Elif (sublist_len == 0):
return True
for x in lst:
if x == sublist[k]:
if (k == 0): s = x
Elif (x != s): s = None
k += 1
if k == sublist_len:
return True
Elif k > 0 and sublist[k-1] != s:
k = 0
return False
Un moyen simple de vérifier si tous les éléments d’une liste se trouvent dans un autre consiste à convertir les deux en ensembles:
def sublist(lst1, lst2):
return set(lst1) <= set(lst2)
Une autre façon de procéder consiste à utiliser collections.Counter
. La deuxième réponse de @ L3viathan est le moyen le plus efficace et le plus rapide de le faire.
def sublist1(lst1, lst2):
ls1 = [element for element in lst1 if element in lst2]
ls2 = [element for element in lst2 if element in lst1]
return ls1 == ls2
def sublist2(lst1, lst2):
def get_all_in(one, another):
for element in one:
if element in another:
yield element
for x1, x2 in Zip(get_all_in(lst1, lst2), get_all_in(lst2, lst1)):
if x1 != x2:
return False
return True
def sublist3(lst1, lst2):
from collections import Counter
c1 = Counter(lst1)
c2 = Counter(lst2)
for item, count in c1.items():
if count > c2[item]:
return False
return True
l1 = ["a", "b", "c", "c", "c", "d", "e"]
l2 = ["c", "a", "c", "b", "c", "c", "d", "d", "f", "e"]
s1 = lambda: sublist1(l1, l2)
s2 = lambda: sublist2(l1, l2)
s3 = lambda: sublist3(l1, l2)
from timeit import Timer
t1, t2, t3 = Timer(s1), Timer(s2), Timer(s3)
print(t1.timeit(number=10000)) # => 0.034193423241588035
print(t2.timeit(number=10000)) # => 0.012621842119714115
print(t3.timeit(number=10000)) # => 0.12714286673722477
Son 2ème chemin est plus rapide d'un ordre de grandeur, mais je voulais mentionner la variante Counter en raison de sa prévalence et de son utilisation en dehors de ce scénario.
C'est facile avec les itérateurs.
>>> a = [0,1,2]
>>> b = [item for item in range(10)]
>>> b
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
[0, 1, 2]
>>> [False, True][set([item in b for item in a]) == set([True])]
True
>>> a = [11, 12, 13]
>>> [False, True][set([item in b for item in a]) == set([True])]
False
b = sublist
et a = list
puis recherchez b en divisant a en longueurs de b
par exemple.
>>> a = [2,4,3,5,7] , b = [4,3]
>>> b in [a[i:len(b)+i] for i in xrange(len(a))]
True
>>> a = [2,4,3,5,7] , b = [4,10]
>>> b in [a[i:len(b)+i] for i in xrange(len(a))]
False
J'ai trouvé que tout ce qui précède ['a', 'b', 'd'] est une sous-liste de ['a', 'b', 'c', 'e', 'd'], qui ne peuvent pas être vrai bien que tous les éléments de la sous-liste soient présents dans la liste. Donc pour maintenir l'ordre et je suis venu avec:
def sublist4(sublist,lst):
#Define an temp array to populate
sub_list=[]
comparable_sublist=[]
#Define two constants to iterate in the while loop
i=0
k=0
#Loop the length of lst
while i < len(lst):
#If the element is in the sublist append to temp array,
if k < len(sublist) and lst[i] == sublist[k]:
sub_list.append(lst[i])
#set a comparable array to the value of temp array
comparable_sublist = sub_list
k += 1
#If the comparable array is the same as the sublist, break
if len(comparable_sublist) == len(sublist):
break
#If the element is not in the sublist, reset temp array
else:
sub_list = []
i += 1
return comparable_sublist == sublist
Bien que la mémoire utilisée ne soit pas très efficace, je trouve que cela fonctionne assez bien avec les petites listes.
def sublist(l1,l2):
s1=" ".join(str(i) for i in l1)
s2=" ".join(str(i) for i in l2)
if s1 in s2:
return True
else:
return False
Je suis venu avec un moyen court pour vérifier la sous-liste
lst1=[1,2,5,6,8,3,2,34,3,4]
lst2=[1,2,3,4]
def sublist(lst1,lst2):
for item in lst2:
try:
lst1.index(item)
except ValueError:
return False
return True
print(sublist(lst1,lst2))
ce que j’ai fait, c’est essentiellement prendre 2 listes lst1 est la plus grande liste et lst2 est la sous-liste que nous recherchons . alors je prends chaque élément du lst2 et vérifie s’il se trouve dans le lst1 en recherchant son index
s'il ne trouve même pas un seul objet, il retourne Faux
si tous les éléments sont couverts, la valeur renvoyée est True
Essaye celui-là!! la sous-liste y ne manque pas à la séquence de la liste x.
x = liste
y = sous-liste
if ([i for i,j in enumerate(y) for k,l in enumerate(x) if i == k and j!=l]):
print("True")
else:
print("False")
Un autre moyen simple consiste à utiliser list comprehension Et utilisez la fonction intégrée all pour vérifier que tous les éléments de list1 figurent dans list2.
Exemple:
list1 = ['1','2']
list2 = ['1','2',3]
all(i in list2 for i in list1)