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

2
Saha 14 avril 2018 à 19:32

6 réponses

Meilleure réponse

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]
3
Aran-Fey 14 avril 2018 à 16:38

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)
1
Nathaniel Jones 14 avril 2018 à 17:01

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
0
jpp 14 avril 2018 à 17:07

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}
1
Aaditya Ura 14 avril 2018 à 16:54

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)
1
Joseph M 14 avril 2018 à 16:36

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]
5
Ajax1234 14 avril 2018 à 16:37