Por que csvwriter.writerow () coloca uma vírgula após cada caractere?

97

Este código abre o url e anexa o /namesno final e abre a página e imprime a string para test1.csv:

import urllib2
import re
import csv

url = ("http://www.example.com")
bios = [u'/name1', u'/name2', u'/name3']
csvwriter = csv.writer(open("/test1.csv", "a"))

for l in bios:
    OpenThisLink = url + l
    response = urllib2.urlopen(OpenThisLink)
    html = response.read()
    item = re.search('(JD)(.*?)(\d+)', html)
    if item:
        JD = item.group()
        csvwriter.writerow(JD)
    else:
        NoJD = "NoJD"
        csvwriter.writerow(NoJD)

Mas eu obtenho este resultado:

J,D,",", ,C,o,l,u,m,b,i,a, ,L,a,w, ,S,c,h,o,o,l,....

Se eu mudar a string para ("JD", "Columbia Law School" ....), então recebo

JD, Columbia Law School...)

Não consegui encontrar na documentação como especificar o delimitador.

Se tento usar delimenter, recebo este erro:

TypeError: 'delimeter' is an invalid keyword argument for this function

Obrigado pela ajuda.

Zeynel
fonte
8
É delimitere não é delimeter: docs.python.org/library/csv.html
John Paulett
Se você está tendo esse problema com o writer.writerow s , passe uma lista de listas e não uma lista de strings.
Noumenon

Respostas:

148

Ele espera uma sequência (por exemplo: uma lista ou tupla) de strings. Você está dando uma única corda. Uma string também é uma sequência de strings, mas é uma sequência de strings de 1 caractere, que não é o que você deseja.

Se você quiser apenas uma string por linha, poderá fazer algo assim:

csvwriter.writerow([JD])

Isso envolve JD (uma string) com uma lista.

Laurence Gonsalves
fonte
Obrigado! Isso consertou. Vou tentar outras respostas também. Eu também criei uma lista vazia JDList = [] e acrescentei JD a ela, que também funciona, mas é mais simples.
Zeynel
1
Agora ele também escreve as aspas da string. Existe uma maneira de contornar isso?
CGFoX
@CGFoX Você pode postar código de exemplo que demonstre isso?
Laurence Gonsalves
writer.writerow([datetime.now().strftime("%Y-%m-%d %H:%M:%S")])escreve a data e hora como"2016-11-05 20:30:19"
CGFoX
@CGFoX Não consigo reproduzir esse comportamento. Eu fico 2016-11-05 13:21:11sem aspas. Qual versão do Python você está usando?
Laurence Gonsalves
5

A classe csv.writer aceita um iterável como argumento de writerow; como strings em Python são iteráveis ​​por caractere, eles são um argumento aceitável para o writerow, mas você obtém a saída acima.

Para corrigir isso, você pode dividir o valor com base em espaços em branco (presumo que seja o que você deseja)

csvwriter.writerow(JD.split())
Gabriel Reid
fonte
1

Isso acontece porque quando o método group () de uma ocorrência de MatchObject retorna apenas um único valor, ele o retorna como uma string. Quando há vários valores, eles são retornados como uma tupla de strings.

Se você estiver escrevendo uma linha, suponho que csv.writer itera sobre o objeto que você passar para ele. Se você passar uma única string (que é iterável), ela itera sobre seus caracteres, produzindo o resultado que você está observando. Se você passar uma tupla de strings, ela obterá uma string real, não um único caractere em cada iteração.

brilhante
fonte