2013-02-21 55 views
0

我在Vim中打開一個文件:Python的過濾:只保留最近的蟒蛇MacPort

py24-sqlalchemy 
py25-beautifulsoup 
py25-beautifulsoup4 
py25-bpython 
py25-epydoc 
py25-icalendar 
py25-ipython 
py25-libgmail 
py25-mechanize 
py25-numpy 
py25-pil 
py25-simplejson 
py25-sphinx 
py25-sqlalchemy 
py25-sqlite 
py25-tkinter 
py25-vobject 
py26-appscript 
py26-beautifulsoup 
py26-bpython 
py26-epydoc 
py26-game 
py26-icalendar 
py26-ipython 
py26-mechanize 
py26-numpy 
py26-pdfminer 
py26-simplejson 
py26-sphinx 
py26-sqlalchemy 
py26-sqlite 
py26-tkinter 
py26-vobject 
py27-appscript 
py27-asciitable 
py27-asciitable 
py27-beautifulsoup 
py27-beautifulsoup4 
py27-blist 
py27-bpython 
py27-chm 
py27-configobj 
py27-dateutil 
py27-epydoc 
py27-game 
py27-gdal 
py27-gtk 
py27-ipython 
py27-lxml 
py27-matplotlib 
py27-mechanize 
py27-mysql 
py27-numpy 
py27-pdfminer 
py27-pil 
py27-prettytable 
py27-progressbar 
py27-psutil 
py27-py2app 
py27-pylint 
py27-pyobjc 
py27-pyobjc-cocoa 
py27-pypdf 
py27-pyqt4 
py27-simplejson 
py27-sphinx 
py27-sqlalchemy 
py27-sqlite 
py27-termcolor 
py27-tkinter 
py27-tz 
py27-wxpython 
py31-appscript 
py31-asciitable 
py31-beautifulsoup4 
py31-blist 
py31-bpython 
py31-game 
py31-lxml 
py31-psutil 
py32-asciitable 
py32-beautifulsoup4 
py32-blist 
py32-bpython 
py32-game 
py32-ipython 
py32-lxml 
py32-psutil 
# ... etc ... (many lines) 

我想過濾線,從而,爲Python版本2.x的範圍內,我只保留最最近的套餐。例如:如果文件同時包含py25-ipython和py26-ipython,我希望py25-ipython消失並停留py26-ipython。始終只保留最新版本,並且每個軟件包始終只有一個版本。

這是我想出來的,但它是可怕的編碼。差不多,看起來像C64-BASIC代碼。

#!/usr/bin/env python2.7 
import sys 
import re 

PATTERN_PYTHON_MACPORT = '^py(2[4567])-(\w[-\w]*)$' 
REGEX_PYTHON_MACPORT = re.compile(PATTERN_PYTHON_MACPORT) 

def main(): 
    packages = {} 
    filtered_lines = [] 
    for line in sys.stdin: 
    match = REGEX_PYTHON_MACPORT.match(line) 
    if match: 
     python_version = int(match.group(1)) 
     package_name = match.group(2) 
     if package_name in packages: 
     packages[package_name].append(python_version) 
     else: 
     packages[package_name] = [python_version] 
    else: 
     filtered_lines.append(line) 
    for package_name in packages: 
    versions = packages[package_name] 
    if len(versions) == 1: 
     version_to_keep = versions[0] 
    else: 
     version_to_keep = sorted(versions, reverse=True)[0] 
     filtered_lines.append('py{}-{}\n'.format(version_to_keep, 
               package_name)) 
    for line in sorted(filtered_lines): 
    sys.stdout.write(line) 
if __name__ == '__main__': 
    main() 

我該如何讓這個更加Pythonic? Vimscript會更容易嗎?我可能會更喜歡在Vimscript中的解決方案..順便說一句,我是Python和Vimscript的初學者。在這裏學習。代碼示例會很棒。

PS我從Vim內部運行濾波器:'<,'>! /Users/tinosino/Desktop/pyfilter.py

回答

1

這將做(在已經訂購假設你輸入列表)相同。否則,請使用sorted(sys.stdin)。如果您不保留Python 3.x模塊,請刪除'else'子句。

import re 
rex = re.compile('py2\d+-(\S+)') 
modules = {} 
for line in sys.stdin: 
    match = rex.match(line) 
    if match: 
     modules[match.group(1)] = match.group(0) 
    else: 
     modules[line] = line 
print '\n'.join(sorted(modules.values())) 

輸出:

py25-libgmail 
py26-icalendar 
py26-vobject 
py27-appscript 
py27-asciitable 
py27-beautifulsoup 
py27-beautifulsoup4 
py27-blist 
py27-bpython 
py27-chm 
py27-configobj 
py27-dateutil 
py27-epydoc 
py27-game 
py27-gdal 
py27-gtk 
py27-ipython 
py27-lxml 
py27-matplotlib 
py27-mechanize 
py27-mysql 
py27-numpy 
py27-pdfminer 
py27-pil 
py27-prettytable 
py27-progressbar 
py27-psutil 
py27-py2app 
py27-pylint 
py27-pyobjc 
py27-pyobjc-cocoa 
py27-pypdf 
py27-pyqt4 
py27-simplejson 
py27-sphinx 
py27-sqlalchemy 
py27-sqlite 
py27-termcolor 
py27-tkinter 
py27-tz 
py27-wxpython 
py31-appscript 
py31-asciitable 
py31-beautifulsoup4 
py31-blist 
py31-bpython 
py31-game 
py31-lxml 
py31-psutil 
py32-asciitable 
py32-beautifulsoup4 
py32-blist 
py32-bpython 
py32-game 
py32-ipython 
py32-lxml 
py32-psutil 
+0

哇,這是緊湊!因此,如果我理解正確,那麼在掃描具有「最高」版本的行時,您正在使用stdin的屬性進行排序,以便用完整的軟件包名稱替換字典中唯一的值。這顯然意味着過濾出py3.x版本之前..我喜歡'\ S'而不是\ w「+」 - ,這是一個很好的學習。 – Robottinosino 2013-02-21 23:20:44

+1

是的,沒錯。 Python 3.x被正則表達式過濾掉。這就是爲什麼我在循環中添加'else'子句(如果你想保留它們)。如果您不這樣做,請刪除'else'子句,輸出將只包含Python 2.x包。 – isedev 2013-02-21 23:22:15

+0

我在做什麼,這是浪費,是保持所有版本的清單,而不是保持最高。還有什麼其他的概念錯誤? – Robottinosino 2013-02-21 23:23:16