如何比较Python 3中的两个CSV文件 - 模块格式 -

时间:2016-03-06 21:17:58

标签: python csv python-3.x

我有以下代码:

import csv
import subprocess

from subprocess import check_output

# Writing the pacman command output to file in csv format

sysApps = check_output(["pacman", "-Qn"])
sysAppsCSV = csv.DictReader(sysApps.decode('ascii').splitlines(),
                        delimiter=' ', skipinitialspace=True,
                        fieldnames=[ 'name', 'version'])  # Thanks to https://stackoverflow.com/a/8880768/5565713  jcollado

with open('pacman.csv', 'w') as csvfile:
    rows_sys = csv.writer(csvfile)
    rows_sys.writerow(sysAppsCSV)

# Writing the pip command output in csv format

pipApps = check_output(["pip", "list"])
pipAppsCSV = csv.DictReader(pipApps.decode('ascii').splitlines(),
                        delimiter=' ', skipinitialspace=True,
                        fieldnames=[ 'name', 'version'])  # Thanks to https://stackoverflow.com/a/8880768/5565713  jcollado

with open('pip.csv', 'w') as csvfile:
    rows_pip = csv.writer(csvfile)
    rows_pip.writerow(pipAppsCSV)

# Comparing the files

我想比较两个文件,没有必要的文件,它也可以是已经创建的变量的内容,并从pip.csv文件获取结果作为差异,实际上我想知道{4}中的内容{1}}并且不在pip.csv中。 here中的示例并不适用于我的情况,但我会通过列出名称和版本以类似的方式输出结果。

编辑: @Greg Sadetsky感谢您使用您的示例来简化我的代码的建议,但没有解决我的问题,我无法通过这种方式比较列表。我取得了一些进展,但我还没有得到所需的输出:

pacman.csv

当我运行此代码时,我会收到一些大写字母,例如:Imgur

cropped version

好的,所以看完套装之后我就这样做了:

import csv
import subprocess

from subprocess import check_output

#Initializing variables

results_sys = ""
results_pip = ""

# Running the linux commands

sys_apps = set(check_output(["pacman", "-Qn"]).splitlines())
pip_apps = set(check_output(["pip", "list"]).splitlines())

# Saving the outputs of the commands in to a CSV format

for row in sys_apps:
    result = row.decode('ascii').split(sep=" ")
    with open('pacman.csv', 'a') as csvfile:
        rows_sys = csv.writer(csvfile)
        rows_sys.writerow(result)

for row in pip_apps:
    result = row.decode('ascii').split(sep=" ")
    with open('pip.csv', 'a') as csvfile:
        rows_sys = csv.writer(csvfile)
        rows_sys.writerow(result)

# Opening the files and comparing the results

with open('pacman.csv', 'r') as pacmanCSV:
    sys_apps = pacmanCSV.readlines()
    for row in sys_apps:
        apps = row.split(",")
        results_sys = results_sys + " " + apps[0]

with open('pip.csv', 'r') as pipCSV:
    pip_apps = pipCSV.readlines()
    for row in pip_apps:
        apps = row.split(",")
        results_pip = results_pip + " " + apps[0]


results_final = "List of apps installed from pip:\n################################"
for val in results_pip:
    if val not in results_sys:
        results_final = results_final + "\n" + val


print(results_final)

但是我得到了类似的结果,只出现了大写字母中的第一个字母。

1 个答案:

答案 0 :(得分:1)

您可以使用sets比较两个包列表,并轻松找出哪个包在一个列表中而不在另一个列表中。

您是否绝对需要浏览CSV文件?您只是在寻找pacmacpip之间的输出差异吗?如果是这样,我在下面创建了一个更简单的例子。

注意:我的机器上没有pacman,但我认为它的输出格式类似于pip。如果没有,您将不得不调整代码。

from subprocess import check_output

sys_apps = set(check_output(["pacman", "-Qn"]).splitlines())
pip_apps = set(check_output(["pip", "list"]).splitlines())

# show packages present in sys_apps that are absent from pip_apps
print sys_apps - pip_apps

编辑:

1-为什么要经历编写CSV文件然后再读回来然后只比较这些集合的麻烦?为什么不简单地检查sys_appspip_apps之间的区别?我想你需要写入CSV文件,你需要从这些文件中读回来然后比较它们的内容。

2-我看到你正在混合Python 2和Python 3代码(你有一个“sep”参数要拆分,但你也在字符串上调用“decode”)。您使用的是哪个版本的Python?

3-我发现你的代码已经改变了一些。正如我在对你的问题的评论中所解释的那样,通过执行for val in results_pip,你正在迭代该字符串的字符,这可能不是你想要做的(你可能想要迭代列表的元素)。

我只会发布代码下半部分的另一个版本:

# Opening the files and comparing the results

with open('pacman.csv', 'r') as pacmanCSV:
    sys_apps = pacmanCSV.readlines()

with open('pip.csv', 'r') as pipCSV:
    pip_apps = pipCSV.readlines()

print "List of apps installed from pip:\n################################"

print set(pip_apps) - set(sys_apps)

正如您将看到的那样,我不是用逗号分隔CSV文件中的行,因为您可以比较包括版本在内的完整软件包名称(我认为检查是否安装了不同版本的软件包很重要通过pip)。如果您只想比较软件包名称(而不是版本),可以将两个with块更改为以下内容:

with open('pacman.csv', 'r') as pacmanCSV:
    sys_apps = [app.split(',')[0] for app in pacmanCSV.readlines()]

with open('pip.csv', 'r') as pipCSV:
    pip_apps = [app.split(',')[0] for app in pipCSV.readlines()]

这会使用拆分提取包名称,然后仅保留包名称,并构建包含sys_apps ans pip_apps的所有包的列表。

请告诉我这是否有帮助!