Python大众传播( ). TypeError:应为字符串或缓冲区,而不是Lis

2024-09-29 21:35:03 发布

您现在位置:Python中文网/ 问答频道 /正文

上下文

代码应该获取一个file对象并使用awk从中提取信息。在

它使用readlines()和'pieceSize'作为参数pieceSize'是readlines()在遍历文件时要处理的MB数。我这样做是希望我的程序不会遇到麻烦,如果需要读取的文件远远大于我的计算机内存。 正在读取的文件有许多行和列。在

下面的代码尝试使用awk从第一行读取第一个字段。在

import os
from subprocess import Popen, PIPE, STDOUT

def extract_info(file_object):
    pieceSize = 16777216 # 16MB
    for line in file_object.readlines(pieceSize):
        eachline = line.rsplit() # removing extra returns
        p = Popen(['awk','{{print `$`1}}'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
        pOut = p.communicate(input=eachline)[0]  
        print(pOut.decode())

错误消息

我收到的错误读起来像。。。在

^{pr2}$

Tags: 文件代码importobjectstdoutlinefileprint
3条回答

您需要将从split返回的列表中的字符串传递给输入:

 pOut, _ = p.communicate(input=eachline[0])

您传递的是line.rsplit()即一个列表,不确定要传递的确切内容,可能需要input=" ".join(eachline),但不管它是什么,它应该是一个字符串,而不是传递给输入的列表本身。另外,您的awk语法似乎不正确。在

您还可以遍历file对象本身,逐行遍历,避免完全读取行。在

^{pr2}$

所以整个代码应该是:

def extract_info(file_object):
    for line in file_object:
        eachline = line.rsplit() # removing extra returns
        p = Popen(['awk','{print $1}'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
        pOut,_ = p.communicate(input=" ".join(eachline))
        print(pOut.decode())

显然,修复eachline逻辑以执行您期望它做的任何事情。在

另一方面,根本不需要使用awk,您可以使用python完成所有这些工作。在

def extract_info(file_object):
    for line in file_object:
        eachline = line.split(None, 1)
        print(eachline[0])

或者更简洁地使用map和extended iterable unpacking for python3:

def extract_info(file_object):
    for i, *_ in map(str.split, file_object):
        print(i)

目前还不完全清楚你期望达到什么样的产出。在

不过,这可能会有所帮助:

  • 为什么要使用awk如果您所做的只是打印一行中的第一个单词,那么您可以使用python。在
  • 如果要读取大于内存的文件,可以使用readlinefor line in file_handler加载每一行,应避免使用readlines()和{}来加载整个文件。在

试试这个:

with open('myfile.txt') as f:
    for line in f:
        first_word = line.split()[0]

发生此错误是因为str.rsplit()返回列表,而Popen.communicate()需要一个字符串(或缓冲区)。这样你就可以通过了。在

这就是问题的原因,但我不知道你为什么要分线。rsplit()将在所有空白上拆分,包括空格、制表符等。这真的是您想要的吗?在

此外,此代码将迭代readlines()返回的第一组行。文件的其余部分未处理。您需要一个外部循环来保持工作状态,直到输入文件耗尽为止(可能在调用代码中没有显示)。然后它对每一行输入调用一次Popen,这将是非常低效的。在

我建议您完全用Python处理处理。line.split()[0]有效地提供了所需的数据(文件的第一列),而无需将其传递给awk。逐行迭代可以节省内存。在

也许发电机是更好的解决方案:

def extract_info(file_object):
    for line in file_object:
        yield line.split()[0]

然后可以在调用代码中对其进行迭代:

^{pr2}$

相关问题 更多 >

    热门问题