Czy istnieje klasa napisów w języku Python, np. StringBuilder
w języku C#?Python ciąg klasy jak StringBuilder w C#?
Odpowiedz
nie ma korelacji jeden-do-jednego. Do bardzo dobry artykuł można znaleźć Efficient String Concatenation in Python:
Budowanie długich ciągów w języku Python progamming może czasami wynik w bardzo powolnym kod uruchomiony. W artykule w tym artykule badam wydajność obliczeniową różnych metod łączenia ciągów znaków .
Należy zauważyć, że ten artykuł został napisany w oparciu o Python 2.2. Testy najprawdopodobniej wyjdą nieco inaczej w nowoczesnej wersji Pythona (CPython zazwyczaj z powodzeniem optymalizuje konkatenację, ale nie chcesz polegać na tym w ważnym kodzie), a wyrażenie generujące, w którym używa on listy, byłoby warte rozważenia . –
Byłoby dobrze wciągnąć w ten artykuł kilka najciekawszych momentów, przynajmniej kilka implementacji (aby uniknąć problemów z rotowaniem linków). – jpmc26
Metoda 1: resultString + = appendString jest najszybszy według testów @ Antoine-tran poniżej – Justas
Python ma kilka rzeczy, które spełniają podobne cele:
- jeden wspólny sposób budowania dużych ciągów kawałków wzrośnie listę ciągów i dołącz go, gdy skończysz. Jest to często używany idiom Pythona.
- Aby zbudować ciągi zawierające dane z formatowaniem, należy zrobić to oddzielnie.
- Aby wstawić i usunąć na poziomie postaci, należy zachować listę długości-jeden ciąg. (Aby to z ciągiem, można by nazwać
list(your_string)
. Można też użyćUserString.MutableString
do tego. (c)StringIO.StringIO
jest przydatna dla rzeczy, które w przeciwnym razie byłoby wziąć plik, ale mniej dla budownictwa ogólnego strun.
Użyłem kodu Olivera Crowa (link podany przez Andrew Hare'a) i zaadaptowałem go trochę, aby dostosować Pythona 2.7.3 (używając pakietu timeit) .Poznałem na moim komputerze, Lenovo T61, 6 GB RAM, Debian GNU/Linux 6.0.6 (squeeze).
Oto wynik dla 10.000 iteracji:
method1: 0.0538418292999 secs process size 4800 kb method2: 0.22602891922 secs process size 4960 kb method3: 0.0605459213257 secs process size 4980 kb method4: 0.0544030666351 secs process size 5536 kb method5: 0.0551080703735 secs process size 5272 kb method6: 0.0542731285095 secs process size 5512 kb
oraz 5.000.000 iteracji (metoda 2 został zignorowany, ponieważ zabrakło tooo powoli, tak jak zawsze):
method1: 5.88603997231 secs process size 37976 kb method3: 8.40748500824 secs process size 38024 kb method4: 7.96380496025 secs process size 321968 kb method5: 8.03666186333 secs process size 71720 kb method6: 6.68192911148 secs process size 38240 kb
Jest dość oczywiste, że Python chłopaki zrobili bardzo dobrą robotę w celu optymalizacji ciąg konkatenacji, a jak Hoare powiedział: „przedwczesna optymalizacja jest źródłem wszelkiego zła” :-)
Wygląda na to, że Hoare nie akceptuje tego: http://hans.gerwitz.com/2004/08/12/premature-optimization-is-the-root-all-evil.html –
Nie jest to przedwczesna optymalizacja, aby uniknąć kruche, zależne od interpretacji optymalizacje. Jeśli kiedykolwiek chcesz przesłać do PyPy lub ryzykować trafieniem [jednym z wielu przypadków subtelnego niepowodzenia] (http://stackoverflow.com/questions/24040198/cpython-string-addition-optimisation-failure-case) w celu optymalizacji, należy rzeczy we właściwy sposób. – Veedrac
Wygląda na to, że metoda 1 jest łatwiejsza do optymalizacji przez kompilator. – mbomb007
stosując metodę 5 od góry (plik pseudo) możemy uzyskać bardzo dobre perf i elastyczność
from cStringIO import StringIO
class StringBuilder:
_file_str = None
def __init__(self):
self._file_str = StringIO()
def Append(self, str):
self._file_str.write(str)
def __str__(self):
return self._file_str.getvalue()
teraz używając go
sb = StringBuilder()
sb.Append("Hello\n")
sb.Append("World")
print sb
W przypadku, gdy jesteś tutaj szukasz szybki sposób ciąg konkatenacji w Pythonie, wtedy nie trzeba specjalnej klasy StringBuilder. Prosta konkatenacja działa równie dobrze bez kary wydajności widzianej w C#.
resultString = ""
resultString += "Append 1"
resultString += "Append 2"
Zobacz Antoine-tran's answer wyników dla
Powołując się na optymalizacje kompilatora jest krucha wydajność. Punktów odniesienia powiązanych z zaakceptowaną odpowiedzią i liczbami podanymi przez Antoine-tran nie należy ufać. Andrew Hare popełnia błąd polegający na tym, że w jego metodach został zawarty numer repr
. To spowalnia wszystkie metody jednakowo, ale zasłania rzeczywistą karę w konstruowaniu struny.
Użyj join
. Jest bardzo szybki i niezawodny.
$ ipython3
Python 3.5.1 (default, Mar 2 2016, 03:38:02)
IPython 4.1.2 -- An enhanced Interactive Python.
In [1]: values = [str(num) for num in range(int(1e3))]
In [2]: %%timeit
...: ''.join(values)
...:
100000 loops, best of 3: 7.37 µs per loop
In [3]: %%timeit
...: result = ''
...: for value in values:
...: result += value
...:
10000 loops, best of 3: 82.8 µs per loop
In [4]: import io
In [5]: %%timeit
...: writer = io.StringIO()
...: for value in values:
...: writer.write(value)
...: writer.getvalue()
...:
10000 loops, best of 3: 81.8 µs per loop
Nie ma wyraźnego analogowe - myślę, że oczekuje się, aby użyć powiązań, String (najprawdopodobniej zoptymalizowane jak powiedziałem wcześniej) lub klasa osób trzecich (wątpię, że są one dużo bardziej wydajny - list w Pythonie są dynamiczne -typed więc bez szybkiego działania char [] dla bufora, jak zakładam). Klasy podobne do Stringbuildera nie są przedwczesną optymalizacją ze względu na wrodzoną funkcję łańcuchów w wielu językach (niezmienność) - która pozwala na wiele optymalizacji (na przykład, odwoływanie się do tego samego bufora dla wycinków/podciągów). Klasa Stringbuilder/stringbuffer/stringstream-like działa dużo szybciej niż konkatenacja łańcuchów (generowanie wielu małych tymczasowych obiektów, które wciąż wymagają alokacji i usuwania śmieci), a nawet formatowanie narzędzi podobnych do printf, bez potrzeby interpretowania narzutów związanych z formatowaniem, które są dość pochłaniające dla wielu połączeń formatujących.
- 1. StringBuilder w Flex
- 2. Konstruktor StringBuilder akceptuje obiekt StringBuilder - dlaczego?
- 3. Definiowanie klasy Python z C
- 4. Doxygen C++ parser ciąg znaków w python?
- 5. Stały ciąg znaków C++ (element klasy)
- 6. Jak klonować() StringBuilder
- 7. Jak zmienia się pojemność StringBuilder?
- 8. Obcinanie ciąg w python
- 9. Konwersja IHtmlContent/TagBuilder ciąg w C#
- 10. Stringbuilder w CIL (MSIL)
- 11. Wywołanie funkcji klasy C++ z Ruby/Python
- 12. Python ciąg "" ": pojedynczy podwójny cudzysłów wewnątrz ciąg
- 13. Niezgodność typu: nie można przekonwertować z StringBuilder na ciąg
- 14. Streamwriter vs StringBuilder
- 15. Jak sformatować ciąg znaków LaTeX w python?
- 16. Uzyskaj nazwę klasy jako ciąg znaków w języku C#
- 17. Python ciąg w ... w składni
- 18. Zmienna globalna Klasy Python
- 19. python jak zarejestrować dynamiczne klasy w module
- 20. Jak utworzyć klasę Python w C?
- 21. Parsować ciąg bson w python?
- 22. jak przekonwertować ciąg c na ciąg d?
- 23. StringBuilder/StringBuffer vs. "+" Operator
- 24. Shifting ciąg w C#
- 25. Definiowanie "boolness" klasy w python
- 26. Dzielenie ciąg w C#
- 27. java outOfMemoryError z stringbuilder
- 28. W jaki sposób Python robi ciąg magii?
- 29. Android StringBuilder vs String Concatenation
- 30. Jak zdefiniować właściwość Python * poza * definicji klasy?
To jest duplikat [odpowiednik Java StringBuffer w języku Python] (https://stackoverflow.com/questions/19926089/python-equivalent-of-java-stringbuffer). ** UWAGA: Odpowiedzi są tu nieaktualne i w rzeczywistości stają się mylące. ** Zobacz [to inne pytanie] (https://stackoverflow.com/questions/19926089/python-equivalent-of-java- stringbuffer) dla odpowiedzi, które są bardziej odpowiednie dla współczesnych wersji Pythona (z pewnością 2.7 i wyżej). –