2

I have to convert the followin code written in Python 2 to Python3:

with open('C:/path_to_csv_file/fold1_1.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    for row, timeseq in izip(fold1, fold1_t):
        spamwriter.writerow([unicode(s).encode("utf-8") +'#{}'.format(t) for s, t in izip(row, timeseq)])

My Python 3 code is the following:

with open('C:/Users/path_to_csv_file/fold1_1.csv', 'wb') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    for row, timeseq in zip(fold1, fold1_t): 
        for s, t in zip(row, timeseq):
            bytes_var = s.encode('utf-8') +'#{}'.format(t).encode('utf-8') 
            spamwriter.writerow(bytes_var)

fold1 contains:

fold1 = ['¢©§','¢©§','¢©§']

fold1_t contains:

fold1_t =[[0, 15, 173999],[0, 457325, 306],[0, 62954, 432]]

When I try to execute the code above I get the following error:

TypeError: a bytes-like object is required, not 'str'

The variable bytes_var is type of bytes so normally it should work. Have I done something wrong with the conversion from Python2 to Python3 to get that error? Thank you.

2
  • What line is the exception being thrown on? Commented Dec 8, 2020 at 13:02
  • @SpoonMeiser At: spamwriter.writerow(bytes_var) Commented Dec 8, 2020 at 13:03

2 Answers 2

1

The csv module is one of the pieces where the conversion Python2 -> Python3 is not really straightforward. The underlying file is expected to be opened as text and no longer as a binary file, but with empty end of lines.

So I would write:

with open('C:/path_to_csv_file/fold1_1.csv', 'w', newline='', encoding='utf-8') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    for row, timeseq in izip(fold1, fold1_t):
        spamwriter.writerow([s +'#{}'.format(t) for s, t in izip(row, timeseq)])

The current error is caused by the csv module sending a unicode string while the undelying file expected bytes.

Sign up to request clarification or add additional context in comments.

Comments

1

You'll need to change your wb to w. Also, in python 3, you can do formatted strings by directly passing the expression into the curly braces of the string, so the

s.encode('utf-8') +'#{}'.format(t).encode('utf-8')

can be

f'{s}#{t}'.encode('utf-8') 

Altogether:

import csv

fold1 = ['¢©§','¢©§','¢©§']
fold1_t =[[0, 15, 173999], [0, 457325, 306], [0, 62954, 432]]

with open('C:/path_to_csv_file/fold1_1.csv', 'w') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
    for row, timeseq in zip(fold1, fold1_t): 
        for s, t in zip(row, timeseq):
            bytes_var = s.encode('utf-8') + f'#{t}'.encode('utf-8') 
            spamwriter.writerow(bytes_var)

6 Comments

Thank you for your response. The code gets executed like that, but 'w' isn't different from 'wb' ?
@C96 What do you mean?
Please correct me if I am wrong but the file would not contain different information if I open it in binary mode with 'wb' instead of 'w' ?
@C96 Can you show me what the file will contain when you run the python 2 code?
For example that is the first line of fold1_1 b'\xc2\xa2#0',b'\xc2\xa9#15',b'\xc2\xa7#173999'
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.