我试图提取一个特定的行作为文件中的变量。在
这是我的内容测试.txt在
#first set
Task Identification Number: 210CT1
Task title: Assignment 1
Weight: 25
fullMark: 100
Description: Program and design and complexity running time.
#second set
Task Identification Number: 210CT2
Task title: Assignment 2
Weight: 25
fullMark: 100
Description: Shortest Path Algorithm
#third set
Task Identification Number: 210CT3
Task title: Final Examination
Weight: 50
fullMark: 100
Description: Close Book Examination
这是我的密码
^{pr2}$我想做的是:
taskNumber is 210CT1
taskTitle is Assignment 1
weight is 25
fullMark is 100
desc is Program and design and complexity running time
and loop until the third set
但输出中出现错误
ValueError: not enough values to unpack (expected 5, got 2)
SwiftsNamesake的回应
我试过你的密码。我仍然收到一个错误。在
ValueError: too many values to unpack (expected 5)
这是我用你的代码做的尝试
from itertools import zip_longest
def chunks(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return zip_longest(*args, fillvalue=fillvalue)
with open(home + '\\Desktop\\PADS Assignment\\210CT.txt', 'r') as mod:
for group in chunks(mod.readlines(), 5+2, fillvalue=''):
# Choose the item after the colon, excluding the extraneous rows
# that don't have one.
# You could probably find a more elegant way of achieving the same thing
l = [item.split(': ')[1].strip() for item in group if ':' in item]
taskNumber , taskTile , weight, fullMark , desc = l
print(taskNumber , taskTile , weight, fullMark , desc, sep='|')
如前所述,您需要某种类型的分块。我们也需要完全忽略文件中不相关的行。我已经用下面一些不错的Python巫术实现了这样一个函数。在
它也可能适合使用namedtuple来存储值。namedtuple是一种非常简单的对象类型,它只存储一些不同的值——例如,2D空间中的一个点可能是一个带有x和y字段的namedtuple。这是Python documentation中给出的示例。如果您愿意的话,您应该参考该链接以了解有关namedtuples及其用法的更多信息。我已经使用字段
["number", "title", "weight", "fullMark", "desc"]
创建了一个任务类。在由于变量都是任务的属性,所以为了简洁明了,使用命名元组可能是有意义的。在
除此之外,我试着坚持你的方法,用结肠分开。我的代码生成输出
这似乎是你想要的-我不知道你的输出要求有多严格。不过,为了达到这个目的,应该相对容易修改。在
下面是我的代码,并给出了一些解释性注释:
^{pr2}$也可以引用任务的每个字段,如下所示:
如果不需要namedtuple方法,可以随意将main for循环的内容替换为
然后你的代码就会恢复正常。在
关于我所做的其他更改的一些注释:
filter
只在满足谓词(line_is_relevant(line)
是True
)的行上迭代它在tin上所说的。在任务实例化中的
*
解压迭代器,因此每一个解析的行都是任务构造函数的一个参数。在表达式
(line.strip().split(": ")[1] for line in task_lines)
是一个生成器。这是必需的,因为我们使用task_lines
同时执行多行,因此对于“chunk”中的每一行,我们将其剥离,用冒号分割,并获取第二个元素,即值。在{{{cd2}对相同函数的引用{cda2}对相同函数的引用{cda2}起作用。
zip
然后尝试从该列表的每个元素生成下一个元素,但是由于n个元素中的每一个都是文件的迭代器,zip
生成文件的n行。直到迭代器耗尽为止。在line_is_relevant
函数使用了“真实性”的概念。一种更详细的实现方法可能是然而,在Python中,每个对象都可以隐式地用于布尔逻辑表达式。在这样的表达式中,空字符串(}为空,它将充当}。如果第一个操作数是falsy,}。在
""
)充当False
,而非空字符串充当True
,因此,如果{False
,line_is_relevant
因此将是{and
运算符也将短路,这意味着第二个操作数将不会被计算,因此,方便地引用line[0]
不会导致{好的,下面是我对
n_lines function
更广泛的解释:首先,
zip
函数允许您一次迭代多个'iterable
'。iterable类似于列表或文件,可以在for循环中查看,因此zip函数可以让您执行以下操作:zip
函数一次从每个列表中返回一个元素的“tuple
”。元组基本上是一个列表,但它是不可变的,所以您不能更改它,因为zip并不希望您更改它给您的任何值,而是希望您对它们做些什么。元组和普通的列表很相似。现在这里有一个有用的技巧是使用“unpacking”来分离元组的每个位,如下所示:一个更简单的解包示例,您可能已经看到过了(Python还允许您在这里省略括号()):
尽管
n-lines function
没有使用这个。现在zip
也可以处理多个参数-您可以压缩三个,四个或任意多个列表。在现在,}构造一个迭代器对象。迭代器有点像一个列表,只是你不能索引它,比如
n_lines
函数将*[iter(read_file)] * n
传递给zip
。这里有几件事要讲——我将从第二部分开始。请注意,第一个*
的优先级低于后面的所有内容,因此它等价于*([iter(read_file)] * n)
。现在,iter(read_file)
所做的是通过调用iter
从{it[0]
。你所能做的就是“迭代它”,就像在for循环中遍历它一样。然后,它将这个迭代器作为它唯一的元素来构建一个长度为1的列表。然后它将这个列表“乘以”n
。在在Python中,使用*运算符和一个列表将其连接到自身
n
次。如果你仔细考虑一下,这是有意义的,因为+
是串联运算符。比如说顺便说一下,这使用了Python的链式比较运算符-
a == b == c
相当于a == b and b == c
,只是b只需要计算一次,这在99%的情况下都不重要。在总之,我们现在知道*操作符复制了一个列表n次。它还有一个属性-它不构建任何新对象。这可能有点让人捉摸不透-
这里l是三个
object
s,但实际上它们都是同一个对象(您可能会认为这是指向同一对象的三个“指针”)。如果要构建一个包含更复杂对象(如列表)的列表,并执行诸如排序之类的就地操作,则会影响列表中的所有元素。在所以
[iter(read_file)] * n
相当于现在,第一个
*
,优先级较低的,再次“解包”这个,但这次并没有将它赋给一个变量,而是赋给zip
的参数。这意味着zip
将列表的每个元素作为一个单独的参数接收,而不仅仅是列表中的一个参数。下面是一个在更简单的情况下如何打开包装的示例:我们现在有了效果
请记住,当你在for循环中对一个file对象进行“迭代”时,你会迭代文件的每一行,所以当zip试图一次“遍历”n个对象中的每一个时,它会从每个对象中绘制一行-但是由于每个对象都是相同的迭代器,所以这行被“消耗”,它绘制的下一行是文件的下一行。从它的n个参数中的每一个进行一轮迭代,生成n行,这就是我们想要的。在
这里的问题是,将行拆分为:并且每行只有1:所以有2个值。 在这一行中:
你告诉它有5个值,但它只找到2个,所以它给你一个错误。在
解决此问题的一种方法是对每个值运行多个for循环,因为不允许更改文件的格式。我会用第一个词把数据分类
^{pr2}$当然,你可以使用一个循环打印,但我太懒了,所以我复制和粘贴:)。 如果您需要帮助或有任何问题,请咨询!!! 此代码假定您在编码方面没有那么先进 祝你好运!!!在
您的
line
变量只得到Task Identification Number: 210CT1
作为其第一个输入。您试图从中提取5个值,方法是用:
拆分它,但是那里只有2个值。在您需要的是将
for
循环分成5个,将每组读为5行,然后将每行除以:
。在相关问题 更多 >
编程相关推荐