Dlaczego csvwriter.writerow () umieszcza przecinek po każdym znaku?

98

Ten kod otwiera adres URL i dołącza /namesna końcu, a następnie otwiera stronę i drukuje ciąg do 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)

Ale otrzymuję ten wynik:

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

Jeśli zmienię ciąg na („JD”, „Columbia Law School” ....), otrzymam

JD, Columbia Law School...)

W dokumentacji nie mogłem znaleźć sposobu określenia separatora.

Jeśli spróbuję użyć, delimenterpojawia się ten błąd:

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

Dzięki za pomoc.

Zeynel
źródło
8
To delimiteri nie delimeter: docs.python.org/library/csv.html
John
1
Jeśli napotykasz ten problem z writer.writerow s , przekaż mu listę list, a nie listę ciągów.
Noumenon

Odpowiedzi:

152

Oczekuje sekwencji (np. Listy lub krotki) ciągów. Dajesz mu pojedynczy ciąg. Ciąg jest również sekwencją ciągów, ale jest to sekwencja 1 ciągów znaków, co nie jest tym, czego chcesz.

Jeśli potrzebujesz tylko jednego ciągu na wiersz, możesz zrobić coś takiego:

csvwriter.writerow([JD])

To otacza JD (ciąg znaków) listą.

Laurence Gonsalves
źródło
Dzięki! To naprawiło. Spróbuję też innych odpowiedzi. Utworzyłem również pustą listę JDList = [] i dołączyłem do niej JD, która również działa, ale jest prostsza.
Zeynel
1
Teraz zapisuje również cudzysłowy łańcucha. Czy jest na to sposób?
CGFoX
@CGFoX Czy możesz opublikować przykładowy kod, który to demonstruje?
Laurence Gonsalves
writer.writerow([datetime.now().strftime("%Y-%m-%d %H:%M:%S")])zapisuje datę"2016-11-05 20:30:19"
godzinę
@CGFoX Nie mogę odtworzyć tego zachowania. Dostaję 2016-11-05 13:21:11bez cytatów. Jakiej wersji Pythona używasz?
Laurence Gonsalves,
6

Klasa csv.writer przyjmuje element iterowalny jako argument funkcji writerow; ponieważ łańcuchy w Pythonie są iterowalne po znaku, są one akceptowalnym argumentem do writerow, ale otrzymujesz powyższe dane wyjściowe.

Aby to poprawić, możesz podzielić wartość na podstawie białych znaków (zakładam, że tego chcesz)

csvwriter.writerow(JD.split())
Gabriel Reid
źródło
1

Dzieje się tak, ponieważ gdy metoda group () instancji MatchObject zwraca tylko jedną wartość, zwraca ją jako ciąg. Gdy istnieje wiele wartości, są one zwracane jako krotka ciągów.

Jeśli piszesz wiersz, myślę, że csv.writer iteruje po obiekcie, który do niego przekazujesz. Jeśli przekażesz pojedynczy ciąg (który jest iterowalny), iteruje on po swoich znakach, dając wynik, który obserwujesz. Jeśli przekażesz krotkę ciągów, otrzyma ona rzeczywisty ciąg, a nie pojedynczy znak w każdej iteracji.

shylent
źródło