Je suis nouveau en python, J'ai une liste comme: A=['a','b','c']
et une liste comme B=[['a','c'],['a','c'],['b','b']]
je veux avoir une liste comme C=[2,1,2]
C stocke l'occurrence des sous-listes que chaque élément de A vient en B cela signifie que 'a' est dans 2 sous-listes 'b' est dans 1 sous-liste et «c» est dans 2 sous-listes, Comment puis-je atteindre cet objectif? Merci
6 réponses
Vous pouvez parcourir en boucle b
et mettre à jour un {{X1} } pour chaque sous-liste, en utilisant set
pour supprimer les doublons:
from collections import Counter
a = ['a','b','c']
b = [['a','c'],['a','c'],['b','b']]
counter = Counter()
for sublist in b:
counter.update(set(sublist))
c = [counter[x] for x in a]
# result: [2, 1, 2]
Vous pouvez utiliser une compréhension de liste avec sum
pour construire C
.
C = [sum(elem in sub for sub in B) for elem in A]
Cela a le même effet que l'utilisation de boucles imbriquées:
C = []
for elem in A:
sum = 0
for sub in B:
sum += elem in sub
C.append(sum)
Voici une solution avec collections.defaultdict
.
from collections import defaultdict
a = ['a','b','c']
b = [['a','c'],['a','c'],['b','b']]
# initialise defaultdict
d = defaultdict(int)
# convert to sets for performance
a_set = set(a)
b_sets = list(map(set, b))
# loop through list of sets
for item in b_sets:
for i in item & a_set:
d[i] += 1
# retrieve counts in correct order
res = list(map(d.get, a))
print(res)
# [2, 1, 2]
Note sur les performances
Cela n'a peut-être pas d'importance, mais le différentiel de performances est intéressant car il montre clairement la surcharge Counter
(4x plus lente).
from collections import defaultdict, Counter
a = ['a','b','c']
b = [['a','c'],['a','c'],['b','b']]
b = b*100000
def dd(a, b):
d = defaultdict(int)
a_set = set(a)
b_sets = list(map(set, b))
for item in b_sets:
for i in item & a_set:
d[i] += 1
return list(map(d.get, a))
def counter(a, b):
counter = Counter()
for sublist in b:
counter.update(set(sublist))
return [counter[x] for x in a]
assert dd(a, b) == counter(a, b)
%timeit dd(a, b) # 414 ms
%timeit counter(a, b) # 1.65 s
Vous pouvez essayer l'approche dict:
A=['a','b','c']
B=[['a','c'],['a','c'],['b','b']]
d={}
for i in A:
for j in B:
if i in j:
if i not in d:
d[i]=1
else:
d[i]+=1
print(d)
Production:
{'c': 2, 'b': 1, 'a': 2}
Vous pouvez boucler et comparer dans les deux listes
a=['a','b','c']
b=[['a','c'],['a','c'],['b','b']]
result = []
for letter in a:
count = 0
for l in b:
if letter in l:
count += 1
result.append(count)
Vous pouvez utiliser sum
:
a=['a','b','c']
b=[['a','c'],['a','c'],['b','b']]
final_list = [sum(i in c for c in b) for i in a]
Production:
[2, 1, 2]