【问题标题】:Inverting a dictionary of <key : list of values> pairs反转 <key : list of values> 对的字典
【发布时间】:2017-10-02 00:13:28
【问题描述】:

我正在编写此代码,该代码将页码映射到该页面上的单词并将其反转,以便创建一个新的有序字典,将每个唯一单词映射到该单词出现的所有页面

例如输入:

words_on_page = {1: ['hi', 'there', 'fred'], 2: ['there', 'we', 'go'], 3: ['fred', 'was', 'there']}

.....应该返回为:

{'hi':[1], 'fred':[1, 3], 'there': [1, 2, 3], 'we' :[2], 'go': [2], 'was': [3]}

到目前为止,我的解决方案是反转字典,但它使关键是该页面上的每个单词都映射到页码。我需要一些如何拆分键中的单词并将它们映射到它们出现的所有页面的列表

def make_index(words_on_page):
"""returnings inverse dictionarty mapping from a word (key) to an 
ordered list of pages on which that word appears"""   

inverted = {}

for page, word in words_on_page.items():        

    word = str(word)

    if word in inverted:

        inverted[word].append(page)

    else:

        inverted[word] = [page]

return inverted 

【问题讨论】:

  • 我想我已经弄清楚了,我只需要添加另一个迭代来遍历单词列表中的所有单词,例如:for page,words_on_page.items()中的单词:for word in words :""

标签: python list dictionary


【解决方案1】:

我用以下方法回答了解决方案(只需要添加另一个迭代)

for page, words in words_on_page.items():        
    for word in words:
        if word in inverted:          
            inverted[word].append(page)
        else:                
            inverted[word] = [page]

return inverted

【讨论】:

【解决方案2】:

您可以使用dict.setdefault 摆脱if 检查:

o = dict()
for k, v in words_on_page.items():
     for i in v:
        o.setdefault(i, []).append(k)        

print(o)
{'fred': [1, 3],
 'go': [2],
 'hi': [1],
 'there': [1, 2, 3],
 'was': [3],
 'we': [2]}

你也可以使用defaultdict:

from collections import defaultdict

o =  defaultdict(list)
for k, v in words_on_page.items():
     o.update({y : o[y] + [x] for x, y in zip([k] * len(v), v)})

print(dict(o))
{'fred': [1, 3],
 'go': [2],
 'hi': [1],
 'there': [1, 2, 3],
 'was': [3],
 'we': [2]}

【讨论】:

  • 我喜欢第一个,简单明了。但是你不会像我的 pandas 解决方案那样把它放在一行中。 :-P
【解决方案3】:

只是为了好玩,熊猫“单线”解决方案:

import pandas as pd

words_on_page = {1: ['hi', 'there', 'fred'], 
                 2: ['there', 'we', 'go'], 3: ['fred', 'was', 'there']}

def make_index(words_on_page):
    return pd.DataFrame(words_on_page.items(), columns=["page", "word"]) \
            .set_index("page")["word"].apply(pd.Series).stack().reset_index() \
            .drop("level_1",1).groupby(0)["page"].unique().apply(list).to_dict()

print make_index(words_on_page)

返回

{'we': [2], 'there': [1, 2, 3], 'fred': [1, 3], 'hi': [1], 'go': [2], 'was': [3]}

【讨论】:

  • 我将 import 语句计为单独的行,因此您的解决方案也是两行。 ;-)
  • 是的,这很公平。 :-)
【解决方案4】:

你可以试试这个:

from itertools import chain
words_on_page = {1: ['hi', 'there', 'fred'], 2: ['there', 'we', 'go'], 3: ['fred', 'was', 'there']}
final_dict = {i:[a for a, b in words_on_page.items() if i in b] for i in chain.from_iterable(words_on_page.values())}

输出:

{'we': [2], 'there': [1, 2, 3], 'fred': [1, 3], 'hi': [1], 'go': [2], 'was': [3]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-01
    • 2022-12-02
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    相关资源
    最近更新 更多