[英]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.