我正在尝试提取混合在句子中的数字。我这样做是通过将句子分成列表中的元素,然后遍历每个元素的每个字符来查找数字。例如:
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']
任何人都可以解释导致此结果的过程吗?
答案 0 :(得分:2)
只需逆转您在另一篇文章中找到的相同过程即可。以相同的顺序嵌套循环:
for i in e:
for e in LP:
if i in ('123456789'):
print(i)
该代码要求同时设置e
和LP
,因此您看到的结果完全取决于列表理解之前运行的其他代码。
如果我们假设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
测试失败。
但是,我们不确定,因为我们不知道在您的环境中最后运行了哪些代码,这些代码将e
和LP
设置为
我不确定您的原始代码为何使用str.split()
,然后遍历每个单词的所有字符。空格永远不会通过您的if
过滤器,因此您可以直接在完整的String
值上循环。 if
测试可以替换为str.isdigit()
test:
digits = [char for char in String if char.isdigit()]
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']