【问题标题】:Python not ignoring empty items in listPython不会忽略列表中的空项目
【发布时间】:2013-05-16 19:26:22
【问题描述】:

我有这段代码可以将一些字符串打印到文本文件中,但我需要 python 忽略每个空项,因此它不会打印空行。
我写了这段代码,很简单,但应该可以解决问题:

lastReadCategories = open('c:/digitalLibrary/' + connectedUser + '/lastReadCategories.txt', 'w')
for category in lastReadCategoriesList:
    if category.split(",")[0] is not "" and category is not None:
        lastReadCategories.write(category + '\n')
        print(category)
    else: print("/" + category + "/")
lastReadCategories.close()

我看不出它有什么问题,但是,python 不断将空项目打印到文件中。所有类别都用这种表示法编写:“category,timesRead”,这就是为什么我要求python查看逗号之前的第一个字符串是否不为空。然后我看看整个项目是否不为空(不是无)。从理论上讲,我想它应该可以工作,对吧?
P.S.:我已经尝试询问 if 来检查 'category' 是否不是 "" 并且不是 " ",仍然是相同的结果。

【问题讨论】:

  • is not "" 是可疑的。 is 检查对象身份,而不是对象相等性。试试if ... != ""
  • 你在循环lastReadCategoriesList;它的定义是什么?
  • 它是一个列表,其中包含类似“category,timesRead”这样的项目,其中“timesRead”是一个被转换成字符串的整数。由于某种原因,我仍然无法确定,一些空项目正在添加到列表中。
  • @millimoose,它仍然会添加空项目,即使使用 != "" 和 != " "
  • @millimoose is not "" 将在 CPython 中工作,但这是解释器的一个怪癖,而不是语言规范的一部分。以下是更多信息:stackoverflow.com/questions/1392433/…

标签: python list for-loop


【解决方案1】:

改为测试布尔真值,并反转您的测试,以便您确定 .split() 首先会起作用,None.split() 会抛出异常:

if category is not None and category.split(",")[0]:

空字符串是'false-y',不需要对它进行任何测试。

您甚至可以只测试:

if category and not category.startswith(','):

为了相同的最终结果。

从 cmets 看来,您的数据中出现了换行符。测试时把它们去掉:

for category in lastReadCategoriesList:
    category = category.rstrip('\n')
    if category and not category.startswith(','):
        lastReadCategories.write(category + '\n')
        print(category)
    else: print("/{}/".format(category))

请注意,您可以在循环内简单地更改category;这样可以避免多次调用.rstrip()

【讨论】:

    【解决方案2】:

    rstrip() 你的类别,然后再写回文件

    lastReadCategories = open('c:/digitalLibrary/' + connectedUser +'/lastReadCategories.txt', 'w')
    for category in lastReadCategoriesList:
    if category.split(",")[0] is not "" and category is not None:
        lastReadCategories.write(category.rstrip() + '\n')
        print(category.rstrip())
    else: print("/" + category + "/")
    lastReadCategories.close()
    

    我能够使用您提供的示例列表对其进行测试(无需将其写入文件):

    lastReadCategoriesList =  ['A,52', 'B,1\n', 'C,50', ',3']
    for category in lastReadCategoriesList:
    if category.split(",")[0] is not "" and category is not None:
        print(category.rstrip())
    else: print("/" + category + "/")
    
    >>> ================================ RESTART ================================
    >>> 
    A,52
    B,1
    C,50
    /,3/
    >>> 
    

    【讨论】:

    • 它停止打印空行...除了 "B,1\n" 中的那个。我的意思是,当我将它打印到 shell 时,它的打印结果和你的完全一样,但不是在文件上。你知道为什么会这样吗? (另外,我将 rstrip() 添加到生成列表的代码部分,并要求它在生成列表后打印列表。它仍然打印“B,1\n”)
    • 你能给我确切的名单吗?
    • @AugustoQ 你是否改变了这部分 lastReadCategories.write(category.rstrip() + '\n')?
    • @AugustoQ 刚刚测试了写入文件...就像一个魅力。
    • 是的,这就是为什么我觉得它很奇怪,因为它应该打印 "B,1\n" 完全没有意义(其他所有问题都已经解决了)
    【解决方案3】:

    测试空字符串(即只有空格而不是'')的经典方法是使用str.strip()

    >>> st='   '
    >>> bool(st)
    True
    >>> bool(st.strip())
    False
    

    这也适用于空字符串:

    >>> bool(''.strip())
    False
    

    你有if category.split(",")[0] is not "" ...,这不是推荐的方式。你可以这样做:

    if category.split(',')[0] and ...
    

    或者,如果你想更啰嗦:

    if bool(category.split(',')[0]) is not False and ...
    

    您可能正在处理 CSV 中前导空格的问题:

    >>> '    ,'.split(',')
    ['    ', '']
    >>> '     ,val'.split(',')
    ['     ', 'val'] 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      相关资源
      最近更新 更多