首页 > 解决方案 > 来自文件的 Python 3 阅读列表 - 附加方括号和引号

问题描述

完整的python新手,使用python 3.6并希望有人能够提供帮助,我正在尝试从darknet/yolo获取输出,并将其与文件中保存的先前命令输出进行比较。我认为我正在错误地写入或读取文件中的列表,因为从文件中读取时我得到了额外的方括号和引号:

["['tvmonitor', 'person']"]

任何使用 [1:-1] 读取变量来修剪变量的尝试都会完全清除内容,因此假定它将正在读取的数据计为一项。

我从检测对象的 darknet/yolo 获取输出并返回一个对象列表,该列表被标记为字节,然后我将其解码为 utf-8。

带有输出的示例代码(请参阅#comments -- 如果格式不正确,请见谅)

# define a few things to be used later
lastsaw = []
olditem = []

# r is a dummy of the output from darknet
r = [b'tvmonitor', b'chair']


print ("this is r")
print (r)
print (type(r))
#output from above code block
# this is r
# [b'tvmonitor', b'chair']
# <class 'list'>


# decode r as utf-8
seenitem = [listitem.decode('utf-8') for listitem in r]

print ("this is seenitem")
print (seenitem)
print (type(seenitem))
# output from above code block:
# this is seenitem
# ['tvmonitor', 'chair']
# <class 'list'>

# read previous runs darknet output in to lastsaw variable
# contents of file is
# ['tvmonitor', 'person']
with open("lastsaw.txt", "r") as filehandle:
 filecontents = filehandle.readlines()
 olditem = (line for line in filecontents)
 lastsaw.extend(olditem)
filehandle.close()


print ("this is lastsaw")
print (lastsaw)
print (type(lastsaw))
# output from above code block (was expecting ['tvmonitor', 'person'] ):
# this is lastsaw
# ["['tvmonitor', 'person']"]
# <class 'list'>


# diff the two lists against each other to find what is missing and what has been added

def Diff(lastsaw, seenitem):
 sawseen = (list(set(lastsaw) - set(seenitem))) 
print("This has gone::>")
print (Diff(lastsaw, seenitem))
# output from above code block (was expecting 'person'] returned):
# This has gone::>
# None

def Diff(seenitem, lastsaw):
 seensaw = (list(set(seenitem) - set(lastsaw))) 
print("This is new::>")
print (Diff(seenitem, lastsaw))
# output from above code block (was expecting ['chair'] returned):
# This is new::>
# None

欣赏任何见解

已编辑——道歉无法添加到评论中,但被询问如何将列表保存到文件中。保存“r”列表的代码(即暗网输出):

这是我调用暗网的部分,将捕获的图像传递给它,我试图在写入之前从字节解码它

#call darknet
if os.path.isfile("/images/img_.jpg"):
      r = (darknet.detect(net, meta, (bytes("/images/img_.jpg", encoding='utf-8'))))
      f= open(b"/output/dknet.txt","w+")
      seenitem = [listitem.decode('utf-8') for listitem in r]
      f.write ('%s' % seenitem)
      f.close ()

稍后在脚本中,我将新文件复制到前一个文件中,因此它是 lastsaw.txt 用于下一次运行

标签: python-3.x

解决方案


您的文件内容只有一行:

['tvmonitor', 'person']

.readlines()将文件中所有行的列表作为字符串列表返回。所以:

with open("lastsaw.txt", "r") as filehandle:
    filecontents = filehandle.readlines() # This contains ["['tvmonitor', 'person']"]
    # olditem = (line for line in filecontents) # This line does nothing relavent
    lastsaw.extend(olditem) # This adds "['tvmonitor', 'person']" to your lastsaw list

所以你可以做两件事之一。

第一个选项(也是我最推荐的)是将文件作为 json 文件读取(前提是文件中的所有文本都是有效的 json):

import json
# Other code...
with open("lastsaw.txt") as filehandle:
    # Note you can do this: lastsaw.extend(lst)
    # Or you can just assign it right away:
    lastsaw  = json.load(filehandle)

或者,不太理想的选项是使用ast.literal_evalwhich 可以将字符串评估为文字 python 对象,例如字符串、整数、列表等:

import ast
# Other code...
with open("lastsaw.txt") as filehandle:
    lastsaw  = ast.literal_eval(filehandle.read())

也请使用至少两个或四个空格来缩进 python 代码,它更具可读性。(4个空格是最常见的)。

- 编辑 -

至于差异,使用 zip 将两个列表组合起来:

lastsaw = ['1', '2', '4']
seenitem = ['1', '3', '4']
# if len(set(x)) > 1 -- The length of the set will be 1 if they match
# else if will be longer than 1 element thus this condition.
dif = [
    (indx, x) for indx, x in enumerate(zip(lastsaw, seenitem))
        if len(set(x)) > 1
]
print(dif)

推荐阅读