C96
C96

Reputation: 529

TypeError: a bytes-like object is required, not 'str' when trying to write in csv file

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.

Upvotes: 2

Views: 1880

Answers (2)

Red
Red

Reputation: 27567

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)

Upvotes: 1

Serge Ballesta
Serge Ballesta

Reputation: 148965

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.

Upvotes: 1

Related Questions