颠倒顺序后,如何了解嵌套列表的列表理解结果?

时间:2018-11-26 22:03:32

标签: python list list-comprehension

我正在尝试提取混合在句子中的数字。我这样做是通过将句子分成列表中的元素,然后遍历每个元素的每个字符来查找数字。例如:

String = "is2 Thi1s T4est 3a"
LP = String.split() 
for e in LP:
    for i in e:
        if i in ('123456789'):
            result += i

这可以给我想要的结果,即['2','1','4','3']。现在,我想以列表理解的方式编写它。阅读List comprehension on a nested list? 帖子后,我了解到正确的代码应为:

[i for e in LP for i in e if i in ('123456789') ]

我用于列表理解方法的原始代码是错误的,但是我试图将我的头绪从结果中总结出来。

我原来的错误代码,颠倒了顺序:

[i for i in e for e in LP if i in ('123456789') ]

我从中得到的结果是:

['3', '3', '3', '3']

任何人都可以解释导致此结果的过程吗?

2 个答案:

答案 0 :(得分:2)

只需逆转您在另一篇文章中找到的相同过程即可。以相同的顺序嵌套循环:

for i in e:
    for e in LP:
        if i in ('123456789'):
            print(i)

该代码要求同时设置eLP,因此您看到的结果完全取决于列表理解之前运行的其他代码

如果我们假设e设置为'3a'(运行循环的代码中LP中的最后一个元素),那么for i in e将运行两次,首先将i设置为'3'。然后,我们得到一个嵌套循环for e in LP,根据给定的输出,LP长4个元素。如此反复进行4次,并且每次迭代i == '3'都通过了if测试,并将'3'添加到输出中。 for i in e:的下一次迭代设置了i = 'a',内部循环再次运行4次,但是if测试失败。

但是,我们不确定,因为我们不知道在您的环境中最后运行了哪些代码,这些代码将eLP设置为

我不确定您的原始代码为何使用str.split(),然后遍历每个单词的所有字符。空格永远不会通过您的if过滤器,因此您可以直接在完整的String值上循环。 if测试可以替换为str.isdigit() test

digits = [char for char in String if char.isdigit()]

甚至是regular expression

digits = re.findall(r'\d', String)

最后,如果这是一个重新排序的难题,则需要将字符串分成一个数字(用于排序)和其余部分(用于加入);对提取的数字上的单词进行排序,并在排序后提取其余部分:

# to sort on numbers, extract the digits and turn to an integer
sortkey = lambda w: int(re.search(r'\d+', w).group())
# 'is2' -> 2, 'Th1s1' -> 1, etc.

# sort the words by sort key
reordered = sorted(String.split(), key=sortkey)
# -> ['Thi1s', 'is2', '3a', 'T4est']

# replace digits in the words and join again
rejoined = ' '.join(re.sub(r'\d+', '', w) for w in reordered)
# -> 'This is a Test'

答案 1 :(得分:1)

从您在评论中提出的问题开始(“您将如何使用我们作为索引的列表对单词进行重新排序?”)

我们可以使用自定义排序来完成此任务。 (请注意,regex不是必需的,但是使正则表达式更简单。请使用任何方法从字符串中提取数字。)

import re

test_string = 'is2 Thi1s T4est 3a'
words = test_string.split()

words.sort(key=lambda s: int(re.search(r'\d+', s).group()))

print(words) # ['Thi1s', 'is2', '3a', 'T4est']

删除号码:

words = [re.sub(r'\d', '', w) for w in words]

最终输出为:

['This', 'is', 'a', 'Test']