Ciąg Pythona jest drukowany jako [u'String ']

142

Z pewnością będzie to łatwe, ale naprawdę mnie to niepokoi.

Mam skrypt, który czyta stronę internetową i analizuje ją za pomocą Beautiful Soup . Z zupy wyciągam wszystkie linki, moim ostatecznym celem jest wydrukowanie linku.contents.

Cały tekst, który analizuję, to ASCII. Wiem, że Python traktuje ciągi znaków jako Unicode i jestem pewien, że jest to bardzo przydatne, po prostu bezużyteczne w moim małym skrypcie.

Za każdym razem, gdy idę wydrukować zmienną zawierającą „String”, [u'String']pojawia się na ekranie. Czy istnieje prosty sposób na przywrócenie tego z powrotem do samego ascii, czy powinienem napisać wyrażenie regularne, aby je usunąć?

gnuchu
źródło
możliwy duplikat znacznie wyraźniej sformułowanego pytania (i odpowiedzi): stackoverflow.com/q/2464959/1390788
Terrabits
Czy to odpowiada na twoje pytanie? Jaki jest przedrostek u w ciągu znaków Pythona?
Terrabits

Odpowiedzi:

118

[u'ABC']byłaby jednoelementową listą ciągów znaków Unicode. Beautiful Soup zawsze tworzy Unicode . Musisz więc przekonwertować listę na pojedynczy ciąg znaków Unicode, a następnie przekonwertować go na ASCII.

Nie wiem dokładnie, skąd masz listy jednoelementowe; składnikiem zawartości byłaby lista ciągów i tagów, co najwyraźniej nie jest tym, co masz. Zakładając, że naprawdę zawsze otrzymujesz listę z jednym elementem i że twój test to tak naprawdę tylko ASCII, użyjesz tego:

 soup[0].encode("ascii")

Jednak sprawdź dokładnie, czy Twoje dane to naprawdę ASCII. To jest dość rzadkie. O wiele bardziej prawdopodobne jest, że jest to latin-1 lub utf-8.

 soup[0].encode("latin-1")


 soup[0].encode("utf-8")

Albo zapytasz Beautiful Soup, jakie było oryginalne kodowanie i odzyskaj je w tym kodowaniu:

 soup[0].encode(soup.originalEncoding)
oefe
źródło
6
W rzeczywistości nie musisz wykonywać kodowania, ponieważ OP widzi tylko łańcuch repr, ponieważ w ten sposób widzisz cokolwiek, gdy drukujesz listę. zupa [0] wystarczy, aby wyświetlić str zamiast repr, pokazując zawartość ciągu, a nie cytat i modyfikator unicode.
ironfroggy
2
W większości przypadków nie powinieneś kodować tekstu reprezentowanego jako Unicode do bajtów: powinieneś drukować Unicode bezpośrednio w Pythonie:print(', '.join([u'ABC' , u'...']))
jfs
26

Prawdopodobnie masz listę zawierającą jeden ciąg znaków Unicode. To reprjest to [u'String'].

Możesz przekonwertować to na listę ciągów bajtów, używając dowolnej odmiany z poniższych:

# Functional style.
print map(lambda x: x.encode('ascii'), my_list)

# List comprehension.
print [x.encode('ascii') for x in my_list]

# Interesting if my_list may be a tuple or a string.
print type(my_list)(x.encode('ascii') for x in my_list)

# What do I care about the brackets anyway?
print ', '.join(repr(x.encode('ascii')) for x in my_list)

# That's actually not a good way of doing it.
print ' '.join(repr(x).lstrip('u')[1:-1] for x in my_list)
ddaa
źródło
1
Prosimy o unikanie takich okropności jak repr(x).lstrip('u')[1:-1]. print ", ".join(my_list)Zamiast tego użyj czegoś takiego jak :, aby sformatować listę ciągów Unicode.
jfs
1
W komentarzu jest napisane: „To właściwie nie jest dobry sposób na zrobienie tego”. Jest tu tylko dla lolz!
ddaa
9
import json, ast
r = {u'name': u'A', u'primary_key': 1}
ast.literal_eval(json.dumps(r)) 

wydrukuje

{'name': 'A', 'primary_key': 1}
osmjit
źródło
1
ta metoda wygląda dla mnie całkiem słodko, dlaczego nie ma głosów? jakikolwiek wpływ na wydajność, o który powinniśmy się martwić?
jrich523
8

W przypadku uzyskiwania dostępu / drukowania list pojedynczych elementów (np. Sekwencyjnych lub filtrowanych):

my_list = [u'String'] # sample element
my_list = [str(my_list[0])]
gevang
źródło
1
robisz rozumienie listy:my_list = [str(my_list[x]) for x in range(len(my_list))]
gevang
4

przekaż dane wyjściowe do funkcji str (), co usunie konwersję wyjścia Unicode. również drukując wynik, usunie z niego tagi u ''.

waweru
źródło
4

[u'String'] jest tekstową reprezentacją listy zawierającej ciąg znaków Unicode w Pythonie 2.

Jeśli uruchomisz, print(some_list)jest to równoważne z
print'[%s]' % ', '.join(map(repr, some_list))np. Utworzeniem reprezentacji tekstowej obiektu Pythona z typem list, repr()funkcja jest wywoływana dla każdego elementu.

Nie należy mylić obiekt Pythona i jego reprezentację tekstową - repr('a') != 'a'a nawet reprezentacji tekstowy różni reprezentacji tekst: repr(repr('a')) != repr('a').

repr(obj)zwraca ciąg zawierający drukowalną reprezentację obiektu. Jego celem jest niedwuznaczna reprezentacja obiektu, który może być przydatny do debugowania w REPL. Często eval(repr(obj)) == obj.

Aby uniknąć wywoływania repr(), możesz wydrukować elementy listy bezpośrednio (jeśli wszystkie są łańcuchami Unicode), np .: print ",".join(some_list)—wypisuje listę ciągów oddzielonych przecinkami:String

Nie koduj ciągu znaków Unicode do bajtów przy użyciu zakodowanego na stałe kodowania znaków, zamiast tego drukuj bezpośrednio Unicode . W przeciwnym razie kod może się nie powieść, ponieważ kodowanie nie może reprezentować wszystkich znaków, np. Jeśli spróbujesz użyć 'ascii'kodowania ze znakami spoza ASCII. Albo kod po cichu tworzy mojibake (uszkodzone dane są przekazywane dalej w potoku), jeśli środowisko używa kodowania, które jest niezgodne z kodowaniem zakodowanym na stałe.

jfs
źródło
3

Użyj dirlub typena 'string', aby dowiedzieć się, co to jest. Podejrzewam, że jest to jeden z obiektów tagów BeautifulSoup, który drukuje jak ciąg, ale tak naprawdę nim nie jest. W przeciwnym razie znajduje się wewnątrz listy i musisz konwertować każdy ciąg oddzielnie.

W każdym razie, dlaczego sprzeciwiasz się używaniu Unicode? Z jakiegoś konkretnego powodu?

sykora
źródło
Patrzę na BeautifulSoup od kilku dni. Nie mogłem dowiedzieć się, jak gnuchu może dostać u ['string'], a nie [u'String ']. Jego komentarz do Andrew Jaffe wydaje się potwierdzać, że jest to lista.
batbrat
3

Naprawdę masz na myśli u'String'?

W każdym razie, czy nie możesz po prostu zrobić str(string)ciągu znaków zamiast łańcucha znaków Unicode? (Powinno to wyglądać inaczej dla Pythona 3, dla którego wszystkie ciągi znaków są w formacie Unicode).

Andrew Jaffe
źródło
Powinienem był być jaśniejszy. Używam str (), ale nadal otrzymuję dane wyjściowe jak poniżej podczas drukowania. [u'ABC '] [u'DEF'] [u'GHI '] [u'JKL'] Dane są usuwane jako tekst ze strony internetowej, a następnie wstawiane do bazy danych (Google Appstore), a następnie pobierane i drukowane.
gnuchu
-1

encode("latin-1") pomogło mi w moim przypadku:

facultyname[0].encode("latin-1")
user1519904
źródło
-1

Może nie rozumiem, dlaczego nie możesz po prostu pobrać elementu.text i przekonwertować go przed użyciem? na przykład (nie wiem, dlaczego miałbyś to zrobić, ale ...) znajdź wszystkie elementy etykiety na stronie internetowej i iteruj między nimi, aż znajdziesz jeden o nazwie MyText

        avail = []
        avail = driver.find_elements_by_class_name("label");
        for i in avail:
                if  i.text == "MyText":

Przekonwertuj ciąg z i i zrób wszystko, co chcesz ... może brakuje mi czegoś w oryginalnej wiadomości? czy to było to, czego szukałeś?

Steven
źródło
Brakuje Ci części, w której pytanie dotyczy tego, jak wykonać „Konwersję ciągu z i”.
Nathan Tuggy
ahhh, dzięki wszystkim komentarzom, myślałem, że problem polegał na uzyskaniu wartości do konwersji
Steven
ale żeby być uczciwym i.text jest rzeczywistą wartością ciągu, nie ma potrzeby "wyciągania go z tablicy", jak sugerowali niektórzy, jeśli na przykład element etykiety ma wartość tekstową [u'String '] i.text będzie String
Steven