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.


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.


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())

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.