当我试图回答这个问题时:regex to split %ages and values in python我注意到我必须从findall的结果重新排序组。例如:
data = """34% passed 23% failed 46% deferred"""
result = {key:value for value, key in re.findall('(\w+)%\s(\w+)', data)}
print(result)
>>> {'failed': '23', 'passed': '34', 'deferred': '46'}
这里findall的结果是:
>>> re.findall('(\w+)%\s(\w+)', data)
>>> [('34', 'passed'), ('23', 'failed'), ('46', 'deferred')]
有没有办法更改/指定使 re.findall返回的组的顺序:
[('passed', '34'), ('failed', '23'), ('deferred', '46')]
只是澄清一下,问题是:
是否可以指定订单或重新排序组以返回re.findall函数?
我使用上面的示例创建了一个字典,以便在您想要更改顺序时使用原因/用例(将键作为值和值作为键)
进一步澄清:
为了处理更大更复杂的正则表达式中的组,您可以命名组,但只有在执行re.search pr re.match时才能访问这些名称。根据我的阅读,findall对元组中返回的组有一个固定的索引,问题是任何人都知道如何修改这些索引。这有助于简化和直观地处理小组。
答案 0 :(得分:7)
根据OP在this comment中的意图进一步澄清,取3,
Ashwin是正确的,findall
不保留命名捕获组(例如(?P<name>regex)
)。 finditer
救援!它逐个返回各个匹配对象。简单的例子:
data = """34% passed 23% failed 46% deferred"""
for m in re.finditer('(?P<percentage>\w+)%\s(?P<word>\w+)', data):
print( m.group('percentage'), m.group('word') )
答案 1 :(得分:0)
正如您在第二个示例中指出的那样,re.findall
会按原始顺序返回组。
问题是标准Python dict
类型不以任何方式保留键的顺序。这是Python 2.x的手册,它使其明确,但在Python 3.x中仍然如此:https://docs.python.org/2/library/stdtypes.html#dict.items
您应该使用的是collections.OrderedDict
:
from collections import OrderedDict as odict
data = """34% passed 23% failed 46% deferred"""
result = odict((key,value) for value, key in re.findall('(\w+)%\s(\w+)', data))
print(result)
>>> OrderedDict([('passed', '34'), ('failed', '23'), ('deferred', '46')])
请注意,必须使用成对构造函数形式(dict((k,v) for k,v in ...
)而不是dict
理解构造函数({k:v for k,v in ...}
)。这是因为后者构造dict
类型的实例,在不丢失键的顺序的情况下无法转换为OrderedDict
...这当然是你想要保留的第一名。
答案 2 :(得分:0)
Per the OP's comment on my first answer:如果你只是想重新排序这样的2元组列表:
[('34', 'passed'), ('23', 'failed'), ('46', 'deferred')]
......看起来像这样,个别元素反转:
[('passed', '34'), ('failed', '23'), ('deferred', '46')]
这是一个简单的解决方案:使用带有切片语法sequence[::-1]
的列表推导来反转单个元组元素的顺序:
a = [('34', 'passed'), ('23', 'failed'), ('46', 'deferred')]
b = [x[::-1] for x in a]
print b