繁体   English   中英

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

[英]Python Dictionary with a list of values for each key

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

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

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

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:]

我认为您最可靠的方法是使用熊猫并合并。

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'])

文件是一个迭代器,这意味着您只能对其进行一次迭代:

>>> 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 line in f2:仅在首次使用时才产生值( for item in data:的第一次迭代f2 = f2.readlines()要解决此问题,您可以执行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会更有意义,因为它们(按定义)仅包含唯一的元素,然后使用.extend而不是.update

import collections
mydict = collections.defaultdict(set)
   ....
        mydict[root].update(words)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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