Python字典,包含每个键的值列表

时间:2016-06-29 15:33:13

标签: python python-2.7 dictionary

我有两个不同的文本文件:一个包含单词及其频率,如下所示:

word1<space>frequency

第二个文件首先包含一个单词,后跟其关联的功能。它看起来像:

word1<tab>feature1<tab>feature2................

第二个文件中的每个单词可能包含任意数量的功能(在我的情况下为0-7)

对于文件1中的每个单词,我想要从文件2中与其关联的所有功能。我想创建一个字典,其中键是来自文件1的单词,其对应的值是从文件2获得的功能列表。

此外,我想要独特的功能,并希望消除文件2中的重复项(我还没有实现)。

我有以下代码,但它仅为文件1中的第一个单词提供所需的输出。mydict确实包含文件1中的所有其他单词,但它们没有任何与之关联的值

mydict = dict()

with open('sample_word_freq_sorted.txt', 'r') as f1:
        data = f1.readlines()

with open('sample_features.txt', 'r') as f2:
        for item in data:
                root = item.split()[0]
                mylist = []
                for line in f2:
                        words = line.split()
                        if words[0] == root:
                                mylist.append(words[1:])
                mydict[root] = mylist

此外,每个键的值是不同的列表,而不仅仅是一个不是我想要的列表。有人可以帮我解决我的代码中的错误吗?

3 个答案:

答案 0 :(得分:0)

mydict = dict()

with open('sample_word_freq_sorted.txt', 'r') as f1:
        data = set([ line.split()[0] for line in f1])

with open('sample_features.txt', 'r') as f2:
        for line in f2:
            word = line.split(' ')[0].strip()
            if word in data:
               mydict[word] = mydict.get(word,[]) + line.split(' ')[1:]

答案 1 :(得分:0)

我认为你最强大的方法是使用Pandas并合并。

df1 = pd.read_csv('sample_word_freq_sorted.txt', delim_whitespace=True)
df2 = pd.read_csv('sample_features.txt', delimeter='\t')
df2 = df2.drop_duplicates()

df = df1.merge(df2, how='left', on='word')

显然,需要针对未发布的数据位进行自定义,但这比尝试在循环中自定义所有内容更不容易出现问题。它还可以轻松处理您的重复问题。

这是否是正确的解决方案还取决于您想要对结果做什么 - 可能在某些情况下让字典版本更好。

编辑:当你的数据没有列标题时,你可以让Pandas给它们起名字,它们是从0开始的整数:

pd.read_csv(path, headers=None)

然后你可以使用整数(例如df [0]将引用名为0的第一列)或稍后更改标题,例如直接指定给df.columns = ['foo', 'bar', baz'],或者你可以在加载中指定标题:

pd.read_csv(path, names=['foo', 'bar', baz'])

答案 2 :(得分:0)

文件是一个迭代器,意味着你只能迭代一遍:

>>> x = (i for i in range(3)) #example iterator
>>> for line in x:
    print(line)

0
1
2
>>> for line in x: #second time produces no results.
    print(line)

>>> 

因此循环for line in f2:仅在第一次使用时生成值(for item in data:的第一次迭代)要修复此问题,您可以执行f2 = f2.readlines(),这样您就有了一个列表可以遍历多次,或者只用一次f2的迭代找到构建字典的方法。

然后您会得到一个子列表列表,因为您.append()的每个单词列表都mylist,而不是.extend其他单词,所以只需更改:

mylist.append(words[1:])

mylist.extend(words[1:])

应该解决你遇到的其他问题。

这似乎是collections.defaultdict派上用场的情况,而不是多次遍历文件为每个特定单词添加项目,dict会自动为每个新单词生成空列表,这样可以让你写你的代码是这样的:

import collections
mydict = collections.defaultdict(list)

with open('sample_features.txt', 'r') as f2:
    for line in f2:
        tmp = line.split()
        root = tmp[0]
        words = tmp[1:]
        #in python 3+ we can use this notation instead of the above three lines:
        #root, *words = line.split()
        mydict[root].extend(words)

虽然由于您只想保留唯一的功能,但使用set而不是list会更有意义,因为它们 - 定义 - 只包含唯一元素,而不是使用{{ 1}}你会使用.extend

.update