Python-字典中的句子

Python-字典中的句子,python,Python,我正试图写一段代码,其中包含一句话: dimension implies direction implies measurement implies the more and the less 并将其转换为字典,其中单词=关键字,值=前面的单词,但第一个单词没有值 基本上应该是: {'and' : 'more' 'dimension' : '' 'direction' : 'implies' 'implies' : 'dimension', 'direction', 'measureme

我正试图写一段代码,其中包含一句话:

dimension implies direction implies measurement implies the more and the less
并将其转换为字典,其中单词=关键字,值=前面的单词,但第一个单词没有值

基本上应该是:

{'and' : 'more'

'dimension' : ''

'direction' : 'implies'

'implies' : 'dimension', 'direction', 'measurement'

'less' : 'the'

'measurement' :'implies'

'more' : 'the'

'the' : 'and', 'implies'}
我写道:

def get_previous_words_dict(text):
    words_list = text.split()
    sentence_dict = {}
    for i in range(0,len(words_list)):
        sentence_dict[words_list[i]] = words_list[i-1]
但它不会将该值添加到键的现有值中,而是替换它,因此,不是为
'implies'
获取3个不同的值,而是仅获取1个值


另外,它没有给单词维度赋值,而是给它赋值更少(因为-1)。

只需将字符串拆分为一个列表,并通过前缀空字符串进行偏移创建另一个列表,然后压缩它并通过迭代创建字典,PS-由于一个键可能有多个值,因此使用默认dict初始化为list而不是dictionary

inp = "dimension implies direction implies measurement implies the more and the less"
l1 = inp.split()
l2 = [""]+l1;
zipped = zip(l1,l2)
from collections import defaultdict
d = defaultdict(list)
for k, v in zipped: 
    d[k].append(v)
print d
如果您不想导入任何东西,请将dict初始化为包含空列表,然后使用相同的逻辑

inp = "dimension implies direction implies measurement implies the more and the less"
l1 = inp.split()
l2 = [""]+l1;
zipped = zip(l1, l2)
d = {x: [] for x in l1}
for k, v in zipped: 
    d[k].append(v)
print d

下面介绍了如何在没有默认dict的情况下执行此操作:

text = 'dimension implies direction implies measurement implies the more and the less'
sentence_dict = {}
prev = ''
for word in text.split():
    if word not in sentence_dict:
        sentence_dict[word] = []
    sentence_dict[word].append(prev)
    prev = word

print(sentence_dict)
输出

{'and': ['more'], 'direction': ['implies'], 'implies': ['dimension', 'direction', 'measurement'], 'less': ['the'], 'measurement': ['implies'], 'the': ['implies', 'and'], 'dimension': [''], 'more': ['the']}

如果不允许导入任何内容,那么一个漂亮的
reduce
操作以及
切片
zip
(所有这些都是Python内置的,不需要导入)可能是一种非常紧凑的方法:

编辑 在向我指出我误解了这个问题后,通过更改
zip()
语句修复了它

# the string - split it immediately into a list of words
# (some words deleted to make it smaller)
words = "dimension implies direction implies the more and the less".split()

# There is a **lot** going on in this line of code, explanation below.
result = reduce(lambda acc, kv: acc.setdefault(kv[0], []).append(kv[1]) or acc,
                zip(words[1:], words[:-1]), {})
# this was the previous - incorrect - zip()
#                zip(words[1::2], words[0::2]), {})
并输出结果(也可编辑)

为完整起见,旧的、错误的结果:

print result
{'the': ['and'], 'implies': ['dimension', 'direction', 'measurement'], 'more': ['the']}
一点解释

将字符串拆分为单词列表后,我们可以将单个单词索引为
words[i]

由问题陈述编辑,生成的dict的键是单词后面的单词,值是第一个单词。因此,我们必须将单词列表转换为每个单词与下一个单词的组合列表。因此,
关键字的列表将是列表[words[1]、words[2]、words[3]、…],与之相关的
值是:[words[0]、words[1]、words[2]、…、words[n-1]]

使用Python
slicing
keys=words[1://code>和
values=words[:-1]

现在我们需要为这些键和值创建一个
dict
,如果同一个键多次出现,则将值聚合到
列表中

dict
有一个方法
.setdefault(key,value)
,如果
key
不在
dict
中,它会将
key
的值初始化为
value
,否则返回当前的值。默认情况下,将所有值初始化到空的
列表中(
[]
),我们可以盲目地调用
.append(…)
。这就是这部分代码的作用:

acc.setdefault(key, []).append( value )
然后是
reduce
。reduce操作将(…)值列表缩减为一个。在这种情况下,我们将把
(key,value)
元组列表缩减为
dict
,在这里我们将所有值累加到它们各自的键中

reduce
采用回调缩减函数和初始元素。这里的初始元素是空的dict
{}
——我们将在继续的过程中填充它

回调归约函数使用两个参数重复调用,累加器和要添加到累加器中的下一个元素。该功能应返回新的蓄能器

在这段代码中,简化步骤基本上是将元素的值添加到元素键的值列表中。(请参见上文-
.setdefault().append()
就是这样做的)

我们只需要得到一个需要处理的
(key,value)
元组列表。这就是内置的
zip
出现的地方
zip
获取两个列表并返回相应元素的元组列表

因此:

生成我们想要的内容:所有
(键、值)
元组的列表

最后,因为归约函数需要返回新的累加器,所以我们必须玩一个小把戏
list.append(…)
返回
None
,即使实际的dict已被修改。因此,我们不能将该值作为下一个累加器返回。因此,我们在此之后添加构造
或acc


由于逻辑
的左侧总是计算为
None
,在Python中,这在逻辑上是
False
,因此右侧总是“已计算”——在本例中是(修改的)dict本身。因此,
的净结果计算为修改后的dict本身,这正是我们需要返回的。

我想知道添加:
如果I==0:stenence\u dict[words\u list[I]='
是否有助于获得第一个索引的空值,因为您分配了
语句dict[words\u list[I]=words\u list[I-1]
不在现有值的后面追加。您应该检查第一个单词的
i==0
。作为旁注:第一个循环可以替换为单词上的直接循环。我们不允许在函数/程序中导入任何额外内容。我曾考虑过创建一个空格并将其添加到字符串中,但是(使用我的代码)我得到了“”:“更少”在字典中也是如此。@PM2Ring谢谢,将其更改为:)FWIW,使用解包而不是索引,即,压缩后的k中的v:d[k]。append(v)
稍微快一点,还有一点更干净。所以我们的想法是制作一个名为prev的新列表?抱歉,只是有点困惑,到底发生了什么code@Nume:
prev
只是一个字符串。它包含前面的单词。循环开始时,它包含一个空字符串。您似乎误解了问题陈述。句子中的每一个字都是关键,不用担心。你的答案对于OP来说可能太超前了,但希望它能让未来的读者受益
acc.setdefault(key, []).append( value )
zip(words[1:], words[:-1])