1
votes

Dans combien de listes un terme apparaît-il

J'ai X nombre de listes, par exemple:

{'potato': 2, 'pie': 2, 'chicken': 1, 'donkey': 1}

Je veux vérifier combien de liste un terme apparaît-il:

Par exemple: p >

Avec les deux listes ci-dessus, je voudrais que le résultat soit:

{'potato': 3, 'pie': 2, 'chicken': 2, 'donkey': 1}

Ma tentative, mais je le faisais complètement mal et je devenais confus et si j'étais égal en adoptant la bonne approche:

x = ['potato', 'pie']
z = ['chicken','chicken','pie','donkey','potato','potato']
list_final = x + z

dict_final = {}

for item in list_final:
    if item in dict_final.keys():
        dict_final.update({item:(dict_final.get(item) + 1)})
    else:
        dict_final.update({item:1})


print(dict_final)

J'ai essayé ceci, mais cela compte juste toutes les fois où il apparaît dans la liste:

(potato,2)
(pie,2)
(chicken,1) - chicken is only one because it appears only in list two, not in list one.
(donkey,1)

mais j'essaye d'obtenir:

[potato, pie]
[chicken,chicken,pie,donkey,potato,potato]


1 commentaires

Si je comprends bien, vous pouvez utiliser set () pour supprimer les doublons de la liste z et vous obtiendrez la réponse attendue.


3 Réponses :


1
votes

Vous devriez parcourir le ensemble d'une liste de vos articles pour ne pas compter deux fois. De plus, vous devrez parcourir tous les éléments et sur vos listes:

list_final = [(i, sum([i in lst for lst in (x, z)])) for i in items]
dict_final = {i: sum([i in lst for lst in (x, z)]) for i in items}

Pour créer une liste de tuples que vous pourriez faire

list_final = []
for i in items:
    cntr = sum([i in lst for lst in (x, z)])
    list_final.append((i, cntr))

... et pour les fans des oneliners:

x = ['potato', 'pie']
z = ['chicken','chicken','pie','donkey','potato','potato']
items = set(x + z)
dict_final = {}

for i in items:
    for lst in [x, z]:
        if i in lst:
            dict_final[i] = dict_final.get(i, 0) + 1

# {'chicken': 1, 'donkey': 1, 'potato': 2, 'pie': 2}


0 commentaires

3
votes

si vous le rendez plus fonctionnel)

from collections import Counter
from functools import reduce

x = ['potato', 'pie']
y = ['chicken','chicken','pie','donkey','potato','potato']
all_lists = [x, y]
dict(Counter(reduce(lambda x, y: x + list(set(y)), all_lists, [])).most_common())
# {'potato': 2, 'pie': 2, 'donkey': 1, 'chicken': 1}


1 commentaires

... et si OP veut avoir un dict comme ils l'ont fait dans l'exemple de code publié de la question, ils n'auront qu'à l'appliquer à la dernière commande: dict (Counter ( ... .most_common ())



1
votes

juste pour l'intérêt: voici les timings des solutions disponibles jusqu'à présent:

import timeit

rep = 100000
n = 5

setup = """
from collections import Counter
from functools import reduce
x = ['potato', 'pie']
z = ['chicken','chicken','pie','donkey','potato','potato']
all_lists = [x, z]
items = set(x + z)
list_final = []
dict_final = {}
"""

fcts = {
        'Counter/reduce':
            'Counter(reduce(lambda x, z: x + list(set(z)), all_lists, [])).most_common()',
        'Counter/reduce into dict':
            'dict(Counter(reduce(lambda x, z: x + list(set(z)), all_lists, [])).most_common())',
        'double for loop dict':
            '''for i in items:
                for lst in (x, z):
                    if i in lst:
                        dict_final[i] = dict_final.get(i, 0) + 1
                        ''',
        'for loop LC into dict':
            '''for i in items:
    cntr = sum([i in lst for lst in (x, z)])
    dict_final[i] = cntr''',
        'for loop LC into list':
            '''for i in items:
    cntr = sum([i in lst for lst in (x, z)])
    list_final.append((i, cntr))''',
        'LC into LC':
            '[(i, sum([1 for lst in (x, z) if i in lst])) for i in items]',
        'LC into DC':
            '{i: sum([i in lst for lst in (x, z)]) for i in items}'
        }

L = max((len(k) for k in fcts.keys()))
results = []
for k, v in fcts.items():
    print(f'timing {k}...')
    tt = timeit.Timer(v, setup=setup)
    t = min(tt.repeat(repeat=rep, number=n))
    results.append((k, t))
for i, (k, t) in enumerate(sorted(results, key=lambda x: x[1])):
    print(f'{i+1}. {k:{L}}:   {t:.3}')

Code pour le timing:

1. double for loop dict    :   8.1e-06
2. for loop LC into dict   :   1.32e-05
3. LC into LC              :   1.37e-05
4. for loop LC into list   :   1.41e-05
5. LC into DC              :   1.41e-05
6. Counter/reduce          :   2.47e-05
7. Counter/reduce into dict:   2.64e-05


0 commentaires