#πŸ”’ Simple list comprehension not working

56 messages Β· Page 1 of 1 (latest)

proven mica
#

Hi, I'm writing a small script to automate some processes for testing purposes.

This is what the relevant part of my code looks like:

def demote_to_user(student_file: str):
    with open(student_file) as student_csv:
        students = [Student(login, int(matriculation_number), first_name, last_name)
                    for student_line in student_csv.readlines()[1:]
                    for login, matriculation_number, _, first_name, last_name in student_line.split(",")]


if __name__ == "__main__":
    demote_to_user("single_sample.csv")
```and here's the `single_sample.csv`:
```csv
login,matriculation number,email,firstname,lastname
user_51,00000051,[email protected],Tilda,MΓΌller

This is the error I get:

Traceback (most recent call last):
  File "/home/samuel/PycharmProjects/PythonProject/main.py", line 120, in <module>
    demote_to_user("single_sample.csv")
  File "/home/samuel/PycharmProjects/PythonProject/main.py", line 89, in demote_to_user
    for login, matriculation_number, _, first_name, last_name in student_line.split(",")]
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 5)

I've ran this version of the code:

def demote_to_user(student_file: str):
    with open(student_file) as student_csv:
        for student_line in student_csv.readlines()[1:]:
            print(student_line)
            print(student_line.split(","))
            login, matriculation_number, _, first_name, last_name = student_line.split(",")
```and it works without any problems.


Now I know that I could just re-write it with that explicit for-loop, but I really want to keep the list comprehension in there, at this point it's just out of spite πŸ’
wispy helmBOT
#

@proven mica

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

paper ice
#

hi

#

doing for ... in student_line.split(',') expects student_line.split(',') to look something like [(a, b, c, d, e), (f, g, h, i, j), ...] rather than [a, b, c, d, e]

#

you're not supposed to use a list comp to just destructure the tuple

safe cedar
proven mica
#

no?

#

ah nvm

#

no, no it doesn't

#

or does it. wait

paper ice
#

it does, but it's not really best practice or readable

safe cedar
#

have you considered using the csv library?

with open("single_sample.csv", "r") as f:
  csvreader = csv.reader(f, delimiter=',')
  for login, matriculation_number, _, first_name, last_name in csvreader:
    ...
bronze hamlet
#

probably better off just writing the logic out in for loops first, then re-factor into comprehensions where it makes sense

proven mica
safe cedar
#

we can help you fix it if you want

proven mica
# safe cedar we can help you fix it if you want

Nah, it's fine. I've got the "manual operation" down to this:

class Student:
    login: str
    matriculation_number: str
    first_name: str
    last_name: str
    email: str = ""

    def __init__(self, login, matriculation_number: int, first_name, last_name):
        self.login = login
        self.matriculation_number = f"{matriculation_number:08}"
        self.first_name = first_name
        self.last_name = last_name
        self.email = f"{login}@artemis.org"

    @staticmethod
    def header():
        return "login,matriculation number,email,firstname,lastname"  # that's the header row

    def __repr__(self):
        return f'{self.login},{self.matriculation_number:08},{self.email},{self.first_name},{self.last_name}'  # print this into the file


# pseudo-code version of gen_random_students, as to not bother you with some minor details
def gen_random_students(...):
    with output_csv:
        output_csv.write(f"{Student.header()}\n")
        for i in range:
            random_student = Student(...)
            output_csv.write(f"{random_student}\n")

So yeah, it's not particularly clean I guess, but it works for my purposes.

#

But I actually found a small "bug" I forgot about rn:

students = [Student(login, int(matriculation_number), first_name, last_name)
            for student_line in (line.strip() for line in student_csv.readlines()[1:])
            for login, matriculation_number, _, first_name, last_name in [student_line.split(",")]]
```I need to put the `.strip()` in order to avoid copying the newline character after the last name
tender holly
#

@proven mica

#

Error Message: ValueError: too many values to unpack (expected 5)

proven mica
#

?

tender holly
#

first Use List Comprehension with Error Handling:

#

Adjust the comprehension to handle cases where the number of values may vary

#

try this ?

#

class Student:
def init(self, login, matriculation_number, first_name, last_name):
self.login = login
self.matriculation_number = matriculation_number
self.first_name = first_name
self.last_name = last_name

def demote_to_user(student_file: str):
with open(student_file) as student_csv:
students = [
Student(login, int(matriculation_number), first_name, last_name)
for student_line in student_csv.readlines()[1:]
if len(student_line.split(",")) == 5 # Ensure exactly 5 values
for login, matriculation_number, _, first_name, last_name in [student_line.split(",")]
]
return students # Return the list of students for further processing if needed

if name == "main":
students = demote_to_user("single_sample.csv")
# You can print or process the students list as needed
for student in students:
print(f"Login: {student.login}, Matriculation Number: {student.matriculation_number}, Name: {student.first_name} {student.last_name}")

wispy helmBOT
#

Hey @tender holly!

Please edit your message to use a code block

```py
print('Hello, world!')
```

This will result in the following:

print('Hello, world!')```
tender holly
#

forgot sry class Student:
def init(self, login, matriculation_number, first_name, last_name):
self.login = login
self.matriculation_number = matriculation_number
self.first_name = first_name
self.last_name = last_name

def demote_to_user(student_file: str):
with open(student_file) as student_csv:
students = [
Student(login, int(matriculation_number), first_name, last_name)
for student_line in student_csv.readlines()[1:]
if len(student_line.split(",")) == 5 # Ensure exactly 5 values
for login, matriculation_number, _, first_name, last_name in [student_line.split(",")]
]
return students # Return the list of students for further processing if needed

if name == "main":
students = demote_to_user("single_sample.csv")
# You can print or process the students list as needed
for student in students:
print(f"Login: {student.login}, Matriculation Number: {student.matriculation_number}, Name: {student.first_name} {student.last_name}")

#

WAIT HWAT

proven mica
#

Rule 10
Do not copy and paste answers from ChatGPT or similar AI tools.

tender holly
#

who does

proven mica
#

You

tender holly
#

i didnt

proven mica
#

LMFAO

#

Did you just post the entire ChatGPT reply by accident?

tender holly
#

nope

#

its not chat gpt

#

its brain gpt

#

xD

#

.

#

😭

#

im just too lazy to help ppls rn

#

ppl*

proven mica
#

I'm just curious cause you apparently have not read the immediate answers, do not know how to format code on Discord, and frankly, noone would write like this:

first Use List Comprehension with Error Handling:
Adjust the comprehension to handle cases where the number of values may vary

Like, you saw my specific input file, and I know that will never change, so I don't need to worry about length verification. If something doesn't work I'd much rather get an aggressive error, rather than sweeping it under the rug.

Also your suggestion would completely remove any reason for demote_to_user to carry that name. Basically "you" rewrote it into a read_students_from_csv file.

proven mica
safe cedar
tender holly
#

bro

#

idk what im typing

#

i just came here

#

did random things

#

xD

safe cedar
# tender holly did random things

in the future i would advice familiarizing yourself with your environment and the etiquette of the community before engaging in online spaces

proven mica
#

!close

wispy helmBOT
#
Python help channel closed with !close

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.