将一个字符串列表与另一个字符串列表进行比较(Python)

3

我正在尝试将两个Excel文档进行比较,它们由大约6000行和4列组成,第一列是域名,其余三列是注释。其中一个文档在某些列中有更新的注释,最终我希望这个脚本能够像批量更新一样,替换旧的过时注释。

到目前为止,我编写的代码打开了这些文档并将它们添加到两个不同的列表中:

import csv

newlist = csv.reader(open('newcomments.csv','rU'), dialect='excel')
export = csv.reader(open('oldcomments.csv', 'rU'), dialect='excel')

for row in newlist:
    olddomain=[]
    domain = row[0:]
    olddomain.append(domain)
    for item in olddomain:
        print item

    for row in export:
        newdomain=[]
        domain= row[0:]
        newdomain.append(domain)
        for item in newdomain:
            print item

列表的输出结果看起来像这样(第二列通常为空):
['example.com', '', 'excomment', 'Parked Page']

尝试比较列表时,我尝试了以下方法:

if item in olddomain != item in newdomain:
                    print "no match"
                else:
                    print "match"

但是发现这种方法似乎不起作用,例如,在两个文件中的第一行包含完全相同的数据,但代码返回“无匹配项”,在两个文件中的第二行也包含相同的数据,但代码返回“匹配”。

问题是我将行保存到列表的方式有问题吗,还是我还缺少其他东西? 我假设有更好的方法来解决这个问题,但我正在利用它来学习更多的Python!

感谢您的时间。


2
似乎不起作用并不是很有信息量。 - joaquin
@joaquin 对不起,例如,两个文件中的第一行包含完全相同的数据,但代码返回“不匹配”,两个文件中的第二行也包含相同的数据,但代码返回“匹配”。 - Christopher Long
2
感谢澄清(我没有投反对票。事实上,我不喜欢人们在不给任何解释的情况下投反对票。这样原帖作者得不到任何教训,而且每个人都会失去声望。真是浪费!) - joaquin
3个回答

8

看起来你正在尝试比较旧的域名列表和新的域名列表。在这些列表建立之后,你想要查看它们之间是否有共性。

在这种情况下,我认为 set() 提供了更丰富的功能,使你的生活更轻松。例如:

>>> olddomains = set(['www.cisco.com', 'www.juniper.com', 'www.hp.com'])
>>> newdomains = set(['www.microsoft.com', 'www.cisco.com', 'www.apple.com'])
>>> olddomains.intersection(newdomains)
set(['www.cisco.com'])
>>>
>>> 'www.google.com' in newdomains
False
>>>

重写您的代码以使用集合将如下所示:
# retain newlist, since that's the output from csv...
for row in newlist:
    olddomain = set([])
    domain = row[0]
    olddomain.add(domain.lower())   # use lower() to ensure no CAPS mess things up
    for item in olddomain:
        print item

而你所询问的代码:

if olddomain.intersection(newdomain) == set([]):
                    print "no match"
                else:
                    print "match"

在决定使用 set() 还是 list() 时,我使用的一般规则是:

  • 如果保留元素的顺序很重要(包括能够使用索引访问它们),请使用 list()
  • 在任何其他情况下,请使用 set()

编辑

既然你问为什么我发布的代码会抛出一个 TypeError,如果你像我一样给 row 赋值,那么你需要使用 row[0] 而不是 row[0:]

>>> row = ['example.com', '', 'excomment', 'Parked Page']
>>> row[0:]
['example.com', '', 'excomment', 'Parked Page']
>>> row[0]
'example.com'
>>> 

我已经修改了我的示例以反映这一点,因为我怀疑问题就出在这里。


我正在尝试运行这段代码,但是它返回了错误:Traceback (most recent call last): File "C:\chris\new project\export\export.py", line 9, in <module> olddomain.add(domain) TypeError: unhashable type: 'list' - Christopher Long
@ChristopherLong,当我执行 olddomain.add(['www.google.com']) 时,我收到一个 TypeError。你需要确保传递给 set.add() 的参数不是 Python 中的 list - Mike Pennington
代码为 "domain = row[0:] olddomain.add(domain)",其中 "domain" 只是 csv 中的一行。 - Christopher Long

3

你很可能只是缺少括号。请注意,以下两行代码是相等的,因为in!=运算符优先级是相等的:

if   item in olddomain  != item in newdomain:
if ((item in olddomain) != item) in newdomain:

你可能想要的是:

您可能需要:

if (item in olddomain) != (item in newdomain):

0

尝试将其转换为集合并执行操作。

示例:

In [1]: a = ['a' , 'b', 'c']

In [2]: b = ['b' , 'a', 'c']

In [3]: set(a) & set(b)

Out[3]: {'a','b','c'}

In [4]: set(b) == set(a) & set(b)

Out[4]: True


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接