Asta m-a derutat mereu. Se pare ca acest lucru ar fi mai frumos:
my_list = ["Hello", "world"]
print(my_list.join("-"))
# Produce: "Hello-world"
Decât acest lucru:
my_list = ["Hello", "world"]
print("-".join(my_list))
# Produce: "Hello-world"
Există un anumit motiv, nu este așa?
L's pentru orice iterable pot fi unite, nu doar liste, dar rezultatul și "unire" sunt întotdeauna siruri de caractere.
De exemplu:
import urllib2
print('\n############\n'.join(
urllib2.urlopen('http://data.stackexchange.com/users/7095')))
Acest lucru a fost discutat în Șir de metode... în cele din urmă filet în Python-Dev atinge, și a fost acceptată de către Guido. Acest thread a început în Iunie 1999, și str.alătură-te a fost inclus în Python 1.6 care a fost lansat în Septembrie 2000 (și acceptate Unicode). Python 2.0 (sprijinit
str` metode, inclusiv "se alăture") a fost lansat în Octombrie 2000.
str.alăturați-vă(seq)
urm.alăturați-vă(str)
urm.reduce(str)
urm.reduce(str)
este dificil pentru nou-veniți.urm.alăturați-vă(str)
introduce neașteptate dependență de secvențe pentru a str/unicode.ca o funcție de built-in va sprijini numai anumite tipuri de date. Deci, folosind o construit în namespace nu este bun. Dacă
join()suporta mai multe tipuri de date, crearea optimizat în aplicare ar fi dificil, dacă va fi implementată folosind
add` metoda atunci's O(n²).Nu există alte motive oferite în acest thread.
Aici sunt unele gânduri suplimentare (propria mea, și prietenul meu's):
Guido's de decizie este înregistrat într-un istoric mail, de a decide pe str.alăturați-vă(seq)`:
Amuzant, dar se pare corect! Barry, du-te pentru ea... --Guido van Rossum
Pentru că se alăture()
metoda este în clasa string, în loc de listă clasa?
Sunt de acord se pare amuzant.
Vezi http://www.faqs.org/docs/diveintopython/odbchelper_join.html:
notă Istorică. Când am aflat prima dată Python, am așteptat să se alăture fi o metodă de o listă, care să ia delimitator ca un argument. O mulțime de oameni simt la fel, și nu există o poveste în spatele metodă se alăture. Înainte pentru Python 1.6, siruri de caractere nu au toate aceste metode utile. Acolo a fost un separat șir de module care conținea toate șir de funcții; fiecare funcția luat un șir de prima sa argument. Funcțiile au fost considerate destul de important pentru a pune pe siruri de caractere ei înșiși, care a făcut sens pentru funcții cum ar fi inferioare, superioare, și split. Dar multe hard-core Python programatori obiectat la noi se alăture metoda, argumentând că aceasta ar trebui să fie o metoda de listă în loc, sau că nu ar trebui să se deplaseze la toate, dar pur și simplu stai o parte din vechiul șir de module (care are încă o mulțime de lucruri utile în ea). nu folosi noua metodă se alăture exclusiv, dar veți vedea codul scris, fie mod, și dacă chiar te deranjează, te puteți folosi șirul vechi.alăturați-vă funcția în loc.
--- Mark Pilgrim, se arunca cu capul în Python
Sunt de acord că nu's contraintuitiv la început, dar nu's un motiv bun. Alăturați-vă poate't fi o metodă de o listă, deoarece:
Există de fapt două se alăture metode (Python 3.0):
>>> b"".join
<built-in method join of bytes object at 0x00A46800>
>>> "".join
<built-in method join of str object at 0x00A28D40>
Dacă vă alăturați a fost o metodă de o listă, atunci ar trebui să verificați argumentele sale pentru a decide care dintre ele pentru a apela. Și puteți't se alăture octet și str împreună, așa cum au acum sens.
Ce e
șir de caractere.alăturați-vă(lista) "în loc de" lista.alăturați-vă(string)
?
Acest lucru este pentru că "se alătură" este un "string" metoda! Se creează un șir de orice iterable. Dacă ne-am blocat metoda pe liste, ceea ce despre atunci când avem iterables care nu't liste?
Ce se întâmplă dacă aveți un tuplu de siruri de caractere? Daca asta a fost o "listă" de metoda, va trebui să arunce în fiecare astfel de iterator de siruri de caractere ca o "listă" înainte de a putea să se alăture elemente într-un singur șir! De exemplu:
some_strings = ('foo', 'bar', 'baz')
Las's roll lista noastră metodă se alăture:
class OurList(list):
def join(self, s):
return s.join(self)
Și să-l folosească, rețineți că trebuie să creați mai întâi o listă de fiecare iterable să se alăture siruri de caractere în care iterable, pierdem atât de memorie și putere de procesare:
>>> l = OurList(some_strings) # step 1, create our list
>>> l.join(', ') # step 2, use our list join method!
'foo, bar, baz'
Deci, vom vedea că trebuie să adăugați un pas suplimentar pentru a utiliza lista noastră metodă, în loc de doar folosind built-string metoda:
>>> ' | '.join(some_strings) # a single step!
'foo | bar | baz'
Algoritmul Python folosește pentru a crea final string cu str.alături de fapt trebuie să treacă peste iterable de două ori, deci, dacă vă oferă un generator de exprimare, trebuie să se materializeze într-o listă înainte de a putea crea final string.
Astfel, în timp ce trece în jurul valorii de generatoare este de obicei mai bine decât list comprehensions, `str.alături este o excepție:
>>> import timeit
>>> min(timeit.repeat(lambda: ''.join(str(i) for i in range(10) if i)))
3.839168446022086
>>> min(timeit.repeat(lambda: ''.join([str(i) for i in range(10) if i])))
3.339879313018173
Cu toate acestea, str.alătură-te operațiunea este încă semantic o "string" operație, așa că încă mai are sens să-l aibă pe
str` obiect decât pe diverse iterables.
Cred ca natural ortogonale funcționare a împărți.
Am înțeles de ce este aplicabil la orice iterable și astfel poate't fi ușor de implementat doar de pe lista.
Pentru lizibilitate, am'd plăcea să-l văd în limba dar nu't cred că este, de fapt posibil - dacă iterability au o interfață atunci acesta ar putea fi adăugat la interfața, dar este doar o convenție și deci nu's nici o centrală modalitate de a adăuga la set de lucruri care sunt iterable.
În primul rând pentru că rezultatul o someString.join()
este un șir de caractere.
Secvență (listă sau tuplu sau orice altceva) nu't apar în rezultat, doar un șir de caractere. Pentru că rezultatul este un șir de caractere, este logic ca o metodă a unui șir.
-
în "-".alăturați-vă(my_list) declară că sunt de conversie de la un șir de elemente de îmbinare-o listă.L's orientate spre rezultate.(doar pentru memorie ușor și înțelegere)
Am face o exhaustivă cheatsheet de methods_of_string pentru referință.
string_methonds_44 = {
'convert': ['join','split', 'rsplit','splitlines', 'partition', 'rpartition'],
'edit': ['replace', 'lstrip', 'rstrip', 'strip'],
'search': ['endswith', 'startswith', 'count', 'index', 'find','rindex', 'rfind',],
'condition': ['isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isnumeric','isidentifier',
'islower','istitle', 'isupper','isprintable', 'isspace', ],
'text': ['lower', 'upper', 'capitalize', 'title', 'swapcase',
'center', 'ljust', 'rjust', 'zfill', 'expandtabs','casefold'],
'encode': ['translate', 'maketrans', 'encode'],
'format': ['format', 'format_map']}
Ambele nu sunt frumos.
șir.alăturați-vă(xs, delimitarea) înseamnă că șirul de module este conștient de existența unei liste, care nu are de unde să știe despre, deoarece șirul de module funcționează numai cu siruri de caractere.
lista.alăturați-vă(delimita) este un pic mai frumos pentru că ne-am're atât de folosit pentru siruri de caractere fiind o fundamentale de tip(și lingual vorbind, ei sunt). Cu toate acestea, acest lucru înseamnă că se alăture trebuie să fie expediate în mod dinamic pentru că în arbitrară context de un.split("\n")
python compiler ar putea să nu știu ce este, și va trebui să se uite în sus(în mod analog cu vtable de căutare), care este costisitoare dacă o faci de multe ori.
dacă python runtime compilatorul știe că lista este o construit în modul, acesta poate sări peste dinamic de căutare și codifica intenție în bytecode direct, întrucât, în caz contrar acesta are nevoie pentru a dinamic a rezolva "alăturați-vă" de "o", care poate fi de mai multe straturi de moștenirea pe apel(deoarece între apeluri, în sensul de a se alătura poate fi schimbat, deoarece python este un limbaj dinamic).
din păcate, aceasta este ultima defect de abstractizare; indiferent de ceea ce abstractizare alegi, captarea va avea sens numai în contextul problemei're încercarea de a rezolva, și, ca atare, niciodata nu poti avea o consistenta abstractizare care nu't devin incompatibile cu bază ideologii cum de a începe lipire-le împreună, fără ambalaj-le în vedere că este în concordanță cu ideologia ta. Știind acest lucru, python's de abordare este mult mai flexibil, deoarece's mai ieftin, l's până la tine să plătească mai mult pentru a face să arate "frumos", fie prin propriul înveliș, sau propriile preprocesor.
Variabilele my_list " și " "-" sunt ambele obiecte. În mod special, au're instanțe ale claselor "listă" și
str, respectiv. A "se alăture" funcția aparține clasei
str. Prin urmare, sintaxa
"-".alăturați-vă(my_list)este folosit pentru obiectul
"-"are
my_list` ca o intrare.