10

正規表現に対してフィルタリングし、一致するものからバージョン番号を抽出する必要があるライブラリファイル名のリストがあります。これはそれを行うための明白な方法です:

libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
versions = []
regex = re.compile('libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)')
for l in libs:
    m = regex.match(l)
    if m:
        versions.append(m.group(1))

これにより、次のリストが生成されます。

['3.3.1', '3.2.0']

それでも、ループは「Pythonスタイル」ではなく、上記の「for」ループをスマートなワンライナーに置き換えることができるはずだと感じています。提案?

4

8 に答える 8

19

リスト内包表記はどうですか?

In [5]: versions = [m.group(1) for m in [regex.match(lib) for lib in libs] if m] 
In [6]: versions
Out[6]: ['3.3.1', '3.2.0']
于 2009-11-03T07:05:11.467 に答える
8

他の方法を示すためにもう1つのワンライナー(正規表現も少しクリーンアップしました):

regex = re.compile(r'^libIce\.so\.([0-9]+\.[0-9]+\.[0-9]+)$')
sum(map(regex.findall, libs), [])

ただし、元のバージョンはすべての提案よりも読みやすいことに注意してください。変更する価値はありますか?

于 2009-11-03T09:05:11.940 に答える
5

あなたはこれを行うことができます:

versions = [m.group(1) for m in [regex.match(l) for l in libs] if m]

あまり読みにくいと思いますが...

多分それは2つのステップでより明確に行われます:

matches = [regex.match(l) for l in line]
versions = [m.group(1) for m in matches if m]
于 2009-11-03T07:05:51.480 に答える
1

標準のforループを使用することについて、Python的でないことは何もありません。ただし、map()関数を使用して、リスト内の各アイテムに対して実行された関数の結果に基づいて新しいリストを生成できます。

于 2009-11-03T07:09:47.650 に答える
0

これはどう:

import re

def matches(regexp, list):
    'Regexp, [str] -> Iterable(Match or None)'
    return (regexp.match(s) for s in list)

libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
regexp = re.compile('libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)')
versions = [m.group(1) for m in matches(regexp, libs) if m is not None]

>>> print versions
['3.3.1', '3.2.0']
于 2009-11-03T07:11:55.523 に答える
0

One way I could think of was to combine 'map' and list comprehension.
The solution looks as below:

import re  
libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']  
versions = []  

regex = re.compile('libIce.so\.([0-9]+\.[0-9]+\.[0-9]+)')  

def match(s):  
    m = regex.match(s)  
    if m:  
        return m.group(1)  

versions = [x for x in map(match,libs) if x]  

于 2009-11-03T07:54:13.550 に答える
0

単純なケースでは、正規表現を気にする必要はありません

>>> libs = ['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
>>> libs
['libIce.so.33', 'libIce.so.3.3.1', 'libIce.so.32', 'libIce.so.3.2.0']
>>> for i in libs:
...   print i.split("so.")
...
['libIce.', '33']
['libIce.', '3.3.1']
['libIce.', '32']
['libIce.', '3.2.0']
>>> for i in libs:
...   print i.split("so.")[-1]
...
33
3.3.1
32
3.2.0
>>>

さらにチェックして、「ドット」が付いているものを取得します。

于 2009-11-03T07:07:36.170 に答える