为什么python在我明确要求不返回时返回一个空列表?

时间:2016-05-10 03:46:04

标签: python

提前道歉 - 我是编码的新手,所以这可能是一个愚蠢的问题!

我尝试扫描本地文本文件(我从http://norvig.com/big.txt下载了文本),然后从该文件中读取并打印随机行到列表中。

但是,我不想打印任何空行,只包含包含文本的行。

所以我尝试使用以下代码:

import random

with open('C:\\big.txt', 'r') as f:
    while True:
        random_line_str = random.choice(f.readlines())
        random_line_lst = random_line_str.split()
        if random_line_lst != []:
            print(random_line_lst)
            break

所以这适用于包含文本的行。但它偶尔会吐出以下错误:

Traceback (most recent call last):
  File "C:\Python\lib\random.py", line 253, in choice
    i = self._randbelow(len(seq))
  File "C:\Python\lib\random.py", line 230, in _randbelow
    r = getrandbits(k)          # 0 <= r < 2**k
ValueError: number of bits must be greater than zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/PycharmProjects/Testing/Test.py", line 5, in <module>
    random_line_str = random.choice(f.readlines())
  File "C:\Python\lib\random.py", line 255, in choice
    raise IndexError('Cannot choose from an empty sequence')
IndexError: Cannot choose from an empty sequence

我还没有弄清楚这里发生的事情,说实话......

我是如何避免这种情况发生的,只返回包含文字的行?

干杯!

3 个答案:

答案 0 :(得分:2)

此行不检查该项是否为空列表,它检查该项是否在空列表中,该列表始终为false(意味着item not in []将始终为真):

if random_line_lst not in []:

你可以做的是因为bool([])是假的,只需这样做:

if random_line_lst:

如果您可能明确检查空列表,请使用!=运算符。

if random_line_lst != []:

使用上述代码,您的代码将成为:

import random

with open('C:\\big.txt', 'r') as f:
    while True:
        random_line_str = random.choice(f.readlines())
        random_line_lst = random_line_str.split()
        if random_line_lst:
            print(random_line_lst)
            break

编辑

对于random.choice,问题是您在random.choice上反复拨打f.readlines()。 Readlines仅在第一次调用时返回每一行,之后它将返回一个空序列。 random.choice无法从空序列中选择项目。这是一个更好的策略:

import random

with open('C:\\big.txt', 'r') as f:
    lines = f.readlines()
    while True:
        random_line_str = random.choice(lines)
        random_line_lst = random_line_str.split()
        if random_line_lst:
            print(random_line_lst)
            break

或者,如果您可以脱离随机性,请使用以下内容:

with open('C:\\big.txt', 'r') as f:
    for line in f:
        line_lst = line.split()
        if line_lst:
            print(line_lst)
            break

答案 1 :(得分:1)

  

如果random_line_lst不是[]

,则打印出来

不,你没有检查。相反,您正在检查random_line_lst中是否存在列表变量[],这始终为真,因为[]为空并且不存在任何内容。所以if random_line_lst not in []:检查不正确。

而不是你需要检查:

if len(random_line_lst) > 0:

或者是一个捷径(和更好的形式)来检查

if random_line_lst:

因为空列表是假的。

此外,您无法始终在循环内调用f.readlines()。您需要在循环开始之前将这些行保留在变量中,否则下次循环运行时将获得IndexError。原因是在f.readlines()的第一次调用中读取了整个文件,并且在下一个调用文件位置已经在文件末尾,因此下一次读取将返回空列表,除非您寻求文件的零位置。对于您的情况,您可以将readlines()调用移出循环。

with open('C:\\big.txt', 'r') as f:
    lines = f.readlines()
    while True:
        random_line_str = random.choice(lines)

答案 2 :(得分:1)

我觉得你可以在这种情况下使用 strip 方法,因为即使该行是空的,你仍然会有与该行相关联的回车符。所以你可以检查以下情况

line.strip() != '' #checking if the line is empty by removing the Carriage return 

with open('fdf.txt','r') as f:
     for line in f:
        if line.strip() != '' :
            print(line)

希望它有所帮助。