简体   繁体   中英

How add one list with item of a specific keys of a dict in python

I have a list of words ( listwords = ['a', 'b', 'c'] ) and a previously original dict ( dictwords = {'111': '['a', 'a', 'b']', '112': '['b', 'a', 'b']'} ) whose purpose is to create a new dict where the keys will be the listwords and their elements will be the quantity one. extra identification and how many words occur in the original dict. The code looks like this:

for i in listwords:
        addlist= []
        for k, x in dictwords.items():
            if i in x:
                cont = 0
                cont = x.count(i)
                addlist.append(k)
                addlist.append(cont)
                newdict[i] = addlist

The end result should be this below:

a ->  ['111', 2], ['112', 1]
b ->  ['111', 2], ['112', 1]
c ->  ['111', 0], ['112', 0]

ie it was supposed to be a key with its respective count lists in the new dict, but the result that is coming out is this:

a ->  ['111', 2, '112', 1]
b ->  ['111', 2, '112', 1]
c ->  ['111', 0, '112', 0]

Does anyone know where I am going wrong? Should I insert a new list and thus insert in the new dict?

You do not have to iterate over the subarrays, your .count does that for you. Instead, loop over the keys in listwords so that you don't have to check multiple times for the same character.

Try this instead:

for i in listwords:
        addlist= []
        for k, x in dictwords.items():
            addlist.append({k: x.count(i)})
        newdict[i] = addlist

>>> newdict
{'a': [{'111': 2}, {'112': 1}], 'b': [{'111': 1}, {'112': 2}], 'c': [{'111': 0}, {'112': 0}]}

You can also use a simple list/dict comprehension to accomplish your goals:

>>> {i: [{key: dictwords[key].count(i)} for key in dictwords] for i in listwords}
{'a': [{'111': 2}, {'112': 1}], 'b': [{'111': 1}, {'112': 2}], 'c': [{'111': 0}, {'112': 0}]}

Does anyone know where I am going wrong? Should I insert a new list and thus insert in the new dict?

You don't need to insert a new list per se, you just need to change where you're initializing addlist . Assuming you want a list of lists, you need to initialize addlist for every key in dictwords . That means moving addlist = [] under for k, x in dictwords.items(): .

Now, instead of assigning addlist to a key in newdict , you need to have newdict create a list for each letter in listwords and append addlist to the list for each letter. There are a couple of different ways to do this, but a pretty elegant solution would be to use defaultdict from the collections module. Using defaultdict and moving the definition of addlist , you should look like this:

from collections import defaultdict

listwords = ['a', 'b', 'c']
dictwords = {'111': "['a', 'a', 'b']", '112': "['b', 'a', 'b']"}
newdict = defaultdict(list)

for i in listwords:
    for k, x in dictwords.items():
        addlist= []
            if i in x:
                cont = 0
                cont = x.count(i)
                addlist.append(k)
                addlist.append(cont)
                newdict[i].append(addlist)

And printing newdict should give you something like this:

defaultdict(<class 'list'>, {'a': [['111', 2], ['112', 1]], 'b': [['111', 1], ['112', 2]]})

You can of course make the output more pretty for your purposes.

You are right. Right now all the entries are referring to the same list, and you're mutating it.

occurences = {}
for word in list_of_words:
    list_to_store = []
    for key, words in dict_of_words.items():
        list_to_store.append((key, words.count(word)))
    occurences[word] = list_to_store

You could also use a list comprehension:

occurences = {}
for word in list_of_words:
    occurences[word] = [(key, words.count(word))
                        for key, words in dict_of_words.items()]

You can also combine it with a dict comprehension:

occurences = {
    word: [(key, words.count(word))
           for key, words in dict_of_words.items()]
    for word in list_of_words
}

And this looks much more concise.

Output code:

for k, v in occurences.items():
    print(f"{k} -> {v}")

Output:

a -> [('111', 2), ('112', 1)]
b -> [('111', 1), ('112', 2)]
c -> [('111', 0), ('112', 0)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM