Search code examples
python-3.xdictionaryioarchivevalueerror

ValueError: not enough values to unpack (expected 2, got 1) in dictionary


i tried to do all i know but i cant fix this

import re

Alice = {}
nombre = input("Cuál es tu nombre: ")
while True:
    mensaje = input(nombre+": ").lower()
    new_string = re.sub(r"[^a-zA-Z0-9áéíóú ]","",mensaje)
    if new_string in Alice:
        print("Alice:",Alice[new_string])
    else:
        print("Alice: No se que decir a esto, ¡dime que debería decir sobre esto!")
        archivo = open("Alice.txt","a")
        new_answer = input(nombre+": ")
        archivo.write(new_string+" - "+new_answer+" , ")
        archivo.close()
        archivo = open("Alice.txt","r")
        archivolocal = archivo.read()
        print(archivolocal)
        Alice = dict((a.strip(), (b.strip()))  
                      for a, b in (element.split('-')  
                                  for element in archivolocal.split(', ')))
        print(Alice)

i want to transform this archive txt:

hola - Hola! , como estás - ¿Bien, y tu? ,

to a dictionary but it tell me that, and i dont know how to fix it that, because i want to do like, a program to write in the archive txt what's the question and later if the archive.txt dont have the answer, you put the answer and save it in the archive.txt but also in the dictionary of Alice

i tried to do everything i know about python, but i know not much really, i try tu change the name of the variable, try some things, put str before the () and nothing, the same result.

ValueError: not enough values to unpack (expected 2, got 1)


Solution

  • Let's walk down your comprehension:

    1. archivolocal.split(', ') gives ['hola - Hola! ', 'como estás - ¿Bien', 'y tu? ', '']
    2. for each element.split('-') you will get respectively ['hola ', ' Hola! '], ['como estás ', ' ¿Bien'], ['y tu? '] and [''].

    These two last elements contains only a single value, and won't be able to be unpacked into two as for a, b in (element.split('-') requires.

    This is the issue with using such a simple marshalling system.

    However it's easy to improve it. You write new_string + " - " + new_answer + " , " to the archive, so you should use those separators in your split calls.

    And you will also need to filter out the last '' after the first split.

    I would recomment you use a for loop rather than comprehensions in this case as they will make things easier to read.

    archivolocal = "hola - Hola! , como estás - ¿Bien, y tu? , "
    conversation = {}
    for el in archivolocal.split(" , "):
        if el == "":  # could be `if not el` since empty strings are falsy
            continue
        k, v = el.split(" - ", maxsplit=2)  # maxsplit for safety
        conversation[k.strip()] = v.strip()
    

    conversation contains

    {'hola': 'Hola!', 'como estás': '¿Bien, y tu?'}