【问题标题】:ValueError: too many values to unpack (while using a dict with tuple keys)ValueError:解包的值太多(使用带有元组键的字典时)
【发布时间】:2017-08-05 09:56:47
【问题描述】:

我想比较两个 .txt 文件。第一个文件是一个“键”,三个值由制表符分隔(即“项目编号”“响应”和“代码”)。第二个文件包含两个由选项卡分隔的值(“项目编号”和“响应”)。我需要我的程序搜索第一个文件,找到任何与第二个文件匹配的“项目编号/响应”对,然后输出正确的“代码”。如果没有匹配,那么我希望输出只是一个空格(“”)。我不是程序员,但弄清楚这一点会大大减少我花在某些工作任务上的时间。

我发现这个thread 有助于设置我的代码。我想完成同样的事情。

file 1, "Key.txt":  
1   dog C  
2   cat C  
3   bird    C  
4   pig C  
5   horse   C  
1   cat Sem  
2   bat TA  
3   animal  Super  
4   panda   M  
5   pencil  U  

file2, "Uncoded.txt":  
4   pig  
3   animal  
5   bird  
2   bat  
2   cat  
0   
1   fluffy  
0   dog  
1   

desired output:  
4   pig  C  
3   animal  Super  
5   bird    
2   bat  TA  
2   cat  C  
0     
1   fluffy    
0   dog    
1     

下面是我的代码:

f1 = open("Key.txt")  
f2 = open("Uncoded.txt")    
d = {}  

while True:  
    line = f1.readline()  
    if not line:  
        break  
    c0,c1,c2 = line.split('\t')  
    d[(c0,c1)] = (c0,c1,c2)  
while True:  
    line = f2.readline()  
    if not line:  
        break  
    c0,c1 = line.split('\t')  
    if (c0,c1) in d:  
        vals = d[(c0,c1)]  
        print (c0, c1, vals[1])  

f1.close()  
f2.close()

如果我尝试使用制表符 ('\t') 分隔行,则会收到 ValueError: too many values to unpack at the line "c0,c1,c2 = line.split('\t')"

非常感谢您的任何见解或帮助!

【问题讨论】:

  • 如果有一个空行(例如最后),这可能不会被检测到,但split 返回空列表:解压得不是很好。拆分,检查列表的长度,然后解包。
  • 你有不同数量的项目的行,但是你有一组变量c0,c1,c2所以任何时候项目的数量不等于你的变量数量,你要得到一个错误。
  • 你们会建议用字典和元组以外的东西来解决这个问题吗?

标签: python dictionary tuples multiple-columns valueerror


【解决方案1】:

您遇到的问题是您的一个文件中的其中一行没有您期望的项目数。一个可能的原因是额外的换行符(可能在文件末尾)。 Python 会将其视为在最后一个 real 行之后仅包含换行符的行。如果无法将空行分成三部分,您的逻辑将失败。

解决此问题的一种方法是将其拆分为单个变量,而无需解包这些值。然后您可以检查拆分了多少项目,并且只有在达到预期数量时才继续拆包:

while True:  
    line = f1.readline()  
    if not line:  
        break  
    vals = line.split('\t')  # don't unpack immediately
    if len(val) == 3:        # check you got the expected number of items
        c0, c1, c2 = vals    # unpack only if it will work
        d[(c0,c1)] = (c0,c1,c2)
    else:
        print("got unexpected number of values: {}".format(vals) # if not, report the error

这与您的错误无关,但如果您愿意,可以通过使用for 循环而不是while 循环来简化循环。文件对象是可迭代的,产生文件的行(就像你从readline() 得到的一样。最好的一点是你不需要自己寻找文件的结尾,迭代只是在文件结束时结束筋疲力尽:

for line in f1:    # this does the same thing as the first four lines in the code above
    ...

【讨论】:

  • 感谢您的洞察力。我使用了简化的for 循环,还编写了一些代码来帮助python按照设置的方式读取我的文本文件。它现在正在工作!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多