【问题标题】:Can't compare strings in Python无法在 Python 中比较字符串
【发布时间】:2012-09-11 14:40:53
【问题描述】:

我有这段代码应该打开并读取两个文本文件,并在两个文本文件中都存在单词时进行匹配。匹配通过打印“SUCESS”并将单词写入 temp.txt 文件来表示。

dir = open('listac.txt','r')
path = open('paths.txt','r')
paths = path.readlines()
paths_size = len(paths)
matches = open('temp.txt','w')
dirs = dir.readlines()

for pline in range(0,len(paths)):
        for dline in range(0,len(dirs)):
                p = paths[pline].rstrip('\n').split(".")[0].replace(" ", "")
                dd = dirs[dline].rstrip('\n').replace(" ", "")
                #print p.lower()
                #print dd.lower()
                if (p.lower() == dd.lower()):
                        print "SUCCESS\n"
                        matches.write(str(p).lower() + '\n')

listac.txt 格式为

/teetetet
/eteasdsa
/asdasdfsa
/asdsafads
.
. 
...etc

paths.txt 格式为

/asdadasd.php/asdadas/asdad/asd
/adadad.html/asdadals/asdsa/asd
.
.
...etc

因此我使用 split 函数来获取点之前的第一个 /asadasda(在 paths.txt 中)。 问题是这些词似乎永远不会匹配,我什至在每个 IF 语句之前打印了每个比较并且它们是相等的,Python 在比较字符串之前还有其他事情吗?

=======

感谢大家的帮助。按照你的建议,我清理了代码,结果是这样的:

dir = open('listac.txt','r')
path = open('paths.txt','r')
#paths = path.readlines()
#paths_size = len(paths)

for line in path:
        p = line.rstrip().split(".")[0].replace(" ", "")
        for lines in dir:
                d = str(lines.rstrip())
                if p == d:
                        print p + " = " + d

显然,在进入第二个 for 循环之前声明和初始化 p 会对以后的比较产生影响。当我在第二个 for 循环中声明 p 和 d 时,它不起作用。我不知道原因,但如果有人这样做,我正在听:)

再次感谢!

【问题讨论】:

  • 在您的示例中,没有匹配项。
  • 太复杂了。不要使用for pline in range(0,len(paths)),只需使用for pline in paths 遍历元素。为什么rstrip('\n')。可能会有一个额外的\r。只需使用rstrip()
  • 你也可以将p = ...移到内部for循环之外,因为它每次都在做同样的计算。
  • 与其比较两个列表中的每个可能对,不如找到两个集合的交集。

标签: python string compare match readline


【解决方案1】:

尽管我们将整个数据文件读入内存,为什么不尝试使用sets 并获得交集?:

def format_data(x):
    return x.rstrip().replace(' ','').split('.')[0].lower()

with open('listac.txt') as dirFile:
     dirStuff = set( format_data(dline) for dline in dirFile )

with open('paths.txt') as pathFile:
     intersection = dirStuff.intersection( format_data(pline) for pline in pathFile )

for elem in intersection:
    print "SUCCESS\n"
    matches.write(str(elem)+"\n")

我对两个数据集使用了相同的 format_data 函数,因为它们看起来或多或少相同,但如果您愿意,您可以使用多个函数。另请注意,此解决方案仅将两个文件中的 1 个文件读入内存。与对方的交点应该懒惰地计算。

正如 cmets 中所指出的,这并没有尝试保持顺序。但是,如果您确实需要保留订单,请尝试以下操作:

<snip>
...
</snip>

with open('paths.txt') as pathFile:
    for line in pathFile:
        if format_line(line) in dirStuff:
           print "SUCCESS\n"
           #...

【讨论】:

  • 这将导致不同的输出,因为行的顺序将会丢失。很可能这无关紧要。
  • 我更喜欢a &amp; b,而不是a.intersection(b)。 "a & b 中的内容" == "a & b 中的内容"。
  • 太糟糕了,像 ∩ 这样的运算符不是 ASCII,因此(还)不是 Python 的一部分;-)
  • 我再次认为在前 10 分钟内接受答案不是一个好主意,应该被禁止。我看到现在嵌套循环的东西在光学上比设定的解决方案更受欢迎,我感到畏缩。而且我也不认为 user1663160 适合它。
  • 无论如何,使用.index() 的东西来重新建立订单并不是一个好主意。最好只线性遍历提供顺序的输入,并在一组其他输入上使用 in 以确定是否找到匹配项。
【解决方案2】:

我必须查看更多您的数据集才能了解您没有得到匹配的原因。我已将您的一些代码重构为更 pythonic

dirFile = open('listac.txt','r')
pathFile = open('paths.txt','r')
paths = pathFile.readlines()
dirs = dirFile.readlines()

matches = open('temp.txt','w')

for pline in paths:
    p = pline.rstrip('\n').split(".")[0].replace(" ", "")
    for dline in dirs:
        dd = dline.rstrip('\n').replace(" ", "")
        #print p.lower()
        #print dd.lower()
        if p.lower() == dd.lower():
            print "SUCCESS\n"
            matches.write(str(p).lower() + '\n')

【讨论】:

  • +1,但是您可以通过先将dirs 转换为一个集合(dirs = {line.lower() for line in dirFile} 然后检查if p.lower() in dirs)来避免可怕的嵌套循环,然后直接遍历文件,避免readlines() 和所有 rstrip()s 完全。
  • @TimPietzcker 肯定。我会以完全不同的方式写这个。我认为让初学者更容易接触这些东西更有帮助。
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 2023-03-28
相关资源
最近更新 更多