如何将列表推导用于附加操作的for循环

时间:2019-07-12 07:05:39

标签: python list dictionary list-comprehension

我想通过列表理解简化这种构造:

words = {}
counter = 0

for sentence in text:
    for word in sentence:
        if word not in words:
            words[word] = counter
            counter += 1

如果有类似后增量的内容,可以这样写:

words = {word: counter++ for sentence in text for word in sentence if word not in words}

我该如何以pythonic方式进行操作?

例如:

text =
[
['aaa', 'bbb', 'ccc'],
['bbb', 'ddd'],
['aaa', 'ccc', 'eee']
]

所需结果:

words = {'aaa': 1, 'bbb': 2, 'ccc': 3, 'ddd': 4, 'eee': 5}

顺序无关紧要。

UPD:

我找到了一个有趣的解决方案:

words = {}
counter = (x for x in range(10**6))

[words.update({word: counter.next()}) for sentence in text for word in sentence if word not in words]

update方法允许检查字典中的单词是否已经存在。 也许我应该使用len(words)而不是counter.next(),但我认为计数器会更快(O(1)vs. O(dict_size))。

5 个答案:

答案 0 :(得分:0)

您使用字典,然后应使用其setdefault方法,这会使这类任务变得微不足道。

words = {}
for sentence in text:
    for word in sentence:
        words[word] = words.setdefault(word, 0) + 1

答案 1 :(得分:0)

您不能在列表/字典理解中初始化变量。但是,您始终可以使用列表然后按字典理解分两步进行操作:

# We list the different words in the text
list_words = [word for word in sentence for sentence in text]

# Using numpy's unique function and the count() 
# function we use a dictionnary comprehension
dict_words = {word : list_words.count(word) for word in np.unique(list_words)}

答案 2 :(得分:0)

如果您真的想使用列表推导,则可以使用此方法:

def countWords(content):
    allWords = [word for words in content for word in words]
    return {word: allWords.count(word) for word in set(allWords)}

答案 3 :(得分:0)

玩起来有点有趣。您真的不可能一站式完成(没关系,一行解决方案并不总是最好的),但是您可以用所有的理解来做到这一点。

d={}
s = "a a a b b a a b a b a b"
x = [(word, 1) for word in s.split()]
d = {word: sum(cnt for w,cnt in x if w == word) for word,_ in x if not word in d.keys()}

d是将保存字数的目标字典。 s是句子之一(如果您有句子列表,则可以将其扩展为在多个级别上进行提取)。 x是一个中间列表,其中每个('word', 1)的单词都有一对,然后我们使用它们对所有单词进行求和以获得最终计数。

最后,xd的值是:

>>> x
[('a', 1), ('a', 1), ('a', 1), ('b', 1), ('b', 1), ('a', 1), ('a', 1), ('b', 1), ('a', 1), ('b', 1), ('a', 1), ('b', 1)]
>>> d
{'a': 7, 'b': 5}

答案 4 :(得分:0)

有很多方法可以做到这一点。这是不使用任何外部模块的一种衬板:

s = "a a a b b a a b a b a b"
d = [[(out, out.update([(v, out.get(v, 0) + 1)])) for v in s.split()] for out in [{}]][0][0][0]
print(d)

打印:

{'a': 7, 'b': 5}