-1

I have two lists: one contain the name of pages like ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)'] and the other list contain the corresponding page number like [1, 2, 3]

I want to create a dictionary from two lists such that the splitted words from list one as a key and corresponding value from list two as value. And if key already is in dictionary then append value to it.

For the above example I want a dictionary like:

{
 'Barrel': [1],
 '-': [1],
 'Part': [1],
 '1': [1],
 'Petit': [2],
 'Trees': [2],
 # '(sketch)': [2],
 'Island': [3],
 '(sketch)':[2, 3]   #in this line the value appended as the key already has a value 2                                     
}
Markus Meskanen
  • 19,939
  • 18
  • 80
  • 119
Ashvini Maurya
  • 493
  • 1
  • 7
  • 13
  • 3
    can you provide us any attempted code from your part? If you don't have any, this should get you started: http://www.pythonforbeginners.com/dictionary/dictionary-manipulation-in-python – glls May 27 '16 at 06:00

3 Answers3

4

You can use zip() to loop through the two lists simultaneously. If you don't need the dict to be in order, it's much easier to use collections.defaultdict() than a normal dictionary:

import collections

titles =  ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)']
pages =  [1, 2, 3]

d = collections.defaultdict(list)

for title, page in zip(titles, pages):
    for word in title.split():
        d[word].append(page)

Although since your pages is just a list of subsequent numbers, it's probably better to use enumerate so you don't have to update the pages list every time you make changes:

import collections

titles =  ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)']
d = collections.defaultdict(list)

for page, title in enumerate(titles, start=1):
    for word in title.split():
        d[word].append(page)

Now if you do need the dict to be in order, you can use OrderedDict combined with @Keatinge's answer:

import collections

titles =  ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)']
d = collections.OrderedDict()

for title, page in enumerate(titles, start=1):
    for word in title.split():
        if word not in d:
            d[word] = [page]
        else:
            d[word].append(page)

Or if you only need the output to be sorted, use the earlier defaultdict solution and throw in sorted() when outputting the values:

for key in sorted(d.keys()):
    print('{0}: {1}'.format(key, d[key]))

Finally, you could use an OrderedDefaultDict, but most would argue that this is a bit of an overkill for such a simple program.

Community
  • 1
  • 1
Markus Meskanen
  • 19,939
  • 18
  • 80
  • 119
0

You might be surprised that the results are out of order, but that's because dicts in python don't have an order. If you want them ordered you'll need to use something other than a vanilla dict.

titles =  ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)']
pages =  [1, 2, 3]

finalDict = {}
for title, page in zip(titles, pages):
    for word in title.split(" "):
        if word not in finalDict.keys():
            finalDict[word] = [int(page)]
        else:
            finalDict[word] += [int(page)]

print(finalDict)

This outputs:

{'Part': [1], '1': [1], 'Trees': [2], 'Island': [3], 'Barrel': [1], '-': [1], '(sketch)': [2, 3], 'Petit': [2]}
Keatinge
  • 4,330
  • 6
  • 25
  • 44
  • 1
    You can use an [`collections.OrderedDict`](https://pymotw.com/2/collections/ordereddict.html) to order them. – rmorshea May 27 '16 at 06:08
  • 1
    Just figured I'd put it out there. – rmorshea May 27 '16 at 06:11
  • Thanks @Keatinge, this is what I wanted, I'm sorry, by mistake I downvoted your answer, how can I now upvote? I'm really sorry. – Ashvini Maurya May 27 '16 at 06:11
  • @Ashvini, I think you should be able to reverse that, by just upvoting instead. Also you should select this as the correct answer. – rmorshea May 27 '16 at 06:12
  • 2
    Honestly you should mark Markus Meskanen's post as the answer, it's undeniably better. – Keatinge May 27 '16 at 06:17
  • 1
    While my answer might be better, there's really nothing wrong with Keatinge's answer. Please stop downvoting him, or if there's a reason to downvote, let everyone else know too. – Markus Meskanen May 27 '16 at 06:20
  • `if word not in finalDict.keys()` should be replaced with `if word not in finalDict` (it is faster on Python 2 and looks nicer on 2/3) – jamylak May 27 '16 at 07:34
0

List comprehension approach.

Basically double iteration in list comprehension is used here (look more pythonic to me). Another way of iterating would be using itertools.chain.

from collections import defaultdict
d = defaultdict(list)
page_names =  ['Barrel - Part 1', 'Petit Trees (sketch)', 'Island (sketch)']
pages =  [1, 2, 3]

for k, v in [(y, x[1]) for x in zip(page_names, pages) for y in x[0].split(' ')]:
    d[k].append(v)

And to convert the a list with duplicated keys, if the order is not a concern. Then coolections.defaultdict would be quite useful. Though pure base python approach would also work, and it will be something like this:

d = {}
for x in l:
    if x.key not in l:
        d[x.key] = []
    d[x.key].append(x.value)
2342G456DI8
  • 1,819
  • 3
  • 16
  • 29